console-feed-modern
Version:
A React component that displays console logs from the current page, an iframe or transported across a server
440 lines • 33.3 kB
JavaScript
// Const
const TRANSFORMED_TYPE_KEY = '@t';
const CIRCULAR_REF_KEY = '@r';
const KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/;
const GLOBAL = (function getGlobal() {
// NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10
const savedEval = eval;
return savedEval('this');
})();
const ARRAY_BUFFER_SUPPORTED = typeof ArrayBuffer === 'function';
const MAP_SUPPORTED = typeof Map === 'function';
const SET_SUPPORTED = typeof Set === 'function';
const TYPED_ARRAY_CTORS = [
'Int8Array',
'Uint8Array',
'Uint8ClampedArray',
'Int16Array',
'Uint16Array',
'Int32Array',
'Uint32Array',
'Float32Array',
'Float64Array'
];
// Saved proto functions
const arrSlice = Array.prototype.slice;
// Default serializer
const JSONSerializer = {
serialize(val) {
return JSON.stringify(val);
},
deserialize(val) {
return JSON.parse(val);
}
};
// EncodingTransformer
class EncodingTransformer {
constructor(val, transforms) {
this.references = val;
this.transforms = transforms;
this.circularCandidates = [];
this.circularCandidatesDescrs = [];
this.circularRefCount = 0;
}
static _createRefMark(idx) {
const obj = Object.create(null);
obj[CIRCULAR_REF_KEY] = idx;
return obj;
}
_createCircularCandidate(val, parent, key) {
this.circularCandidates.push(val);
this.circularCandidatesDescrs.push({ parent, key, refIdx: -1 });
}
_applyTransform(val, parent, key, transform) {
const result = Object.create(null);
const serializableVal = transform.toSerializable(val);
if (typeof serializableVal === 'object')
this._createCircularCandidate(val, parent, key);
result[TRANSFORMED_TYPE_KEY] = transform.type;
result.data = this._handleValue(serializableVal, parent, key);
return result;
}
_handleArray(arr) {
const result = [];
for (let i = 0; i < arr.length; i++)
result[i] = this._handleValue(arr[i], result, i);
return result;
}
_handlePlainObject(obj) {
const result = Object.create(null);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? `#${key}` : key;
result[resultKey] = this._handleValue(obj[key], result, resultKey);
}
}
const { name } = obj.__proto__.constructor;
if (name !== 'Object') {
result.constructor = { name };
}
return result;
}
_handleObject(obj, parent, key) {
this._createCircularCandidate(obj, parent, key);
return Array.isArray(obj)
? this._handleArray(obj)
: this._handlePlainObject(obj);
}
_ensureCircularReference(obj) {
const circularCandidateIdx = this.circularCandidates.indexOf(obj);
if (circularCandidateIdx > -1) {
const descr = this.circularCandidatesDescrs[circularCandidateIdx];
if (descr.refIdx === -1)
descr.refIdx = descr.parent ? ++this.circularRefCount : 0;
return EncodingTransformer._createRefMark(descr.refIdx);
}
return null;
}
_handleValue(val, parent, key) {
const type = typeof val;
const isObject = type === 'object' && val !== null;
try {
if (isObject) {
const refMark = this._ensureCircularReference(val);
if (refMark)
return refMark;
}
for (const transform of this.transforms) {
if (transform.shouldTransform(type, val))
return this._applyTransform(val, parent, key, transform);
}
if (isObject)
return this._handleObject(val, parent, key);
return val;
}
catch (e) {
return null;
}
}
transform() {
const references = [this._handleValue(this.references, null, null)];
for (const descr of this.circularCandidatesDescrs) {
if (descr.refIdx > 0) {
references[descr.refIdx] = descr.parent[descr.key];
descr.parent[descr.key] = EncodingTransformer._createRefMark(descr.refIdx);
}
}
return references;
}
}
// DecodingTransform
class DecodingTransformer {
constructor(references, transformsMap) {
this.activeTransformsStack = [];
this.visitedRefs = Object.create(null);
this.references = references;
this.transformMap = transformsMap;
}
_handlePlainObject(obj) {
const unescaped = Object.create(null);
if ('constructor' in obj) {
if (!obj.constructor || typeof obj.constructor.name !== 'string') {
obj.constructor = {
name: 'Object'
};
}
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
this._handleValue(obj[key], obj, key);
if (KEY_REQUIRE_ESCAPING_RE.test(key)) {
// NOTE: use intermediate object to avoid unescaped and escaped keys interference
// E.g. unescaped "##@t" will be "#@t" which can overwrite escaped "#@t".
unescaped[key.substring(1)] = obj[key];
delete obj[key];
}
}
}
for (const unsecapedKey in unescaped)
obj[unsecapedKey] = unescaped[unsecapedKey];
}
_handleTransformedObject(obj, parent, key) {
const transformType = obj[TRANSFORMED_TYPE_KEY];
const transform = this.transformMap[transformType];
if (!transform)
throw new Error(`Can't find transform for "${transformType}" type.`);
this.activeTransformsStack.push(obj);
this._handleValue(obj.data, obj, 'data');
this.activeTransformsStack.pop();
parent[key] = transform.fromSerializable(obj.data);
}
_handleCircularSelfRefDuringTransform(refIdx, parent, key) {
// NOTE: we've hit a hard case: object reference itself during transformation.
// We can't dereference it since we don't have resulting object yet. And we'll
// not be able to restore reference lately because we will need to traverse
// transformed object again and reference might be unreachable or new object contain
// new circular references. As a workaround we create getter, so once transformation
// complete, dereferenced property will point to correct transformed object.
const references = this.references;
Object.defineProperty(parent, key, {
// @ts-ignore
val: void 0,
configurable: true,
enumerable: true,
get() {
if (this.val === void 0)
this.val = references[refIdx];
return this.val;
},
set(value) {
this.val = value;
}
});
}
_handleCircularRef(refIdx, parent, key) {
if (this.activeTransformsStack.includes(this.references[refIdx]))
this._handleCircularSelfRefDuringTransform(refIdx, parent, key);
else {
if (!this.visitedRefs[refIdx]) {
this.visitedRefs[refIdx] = true;
this._handleValue(this.references[refIdx], this.references, refIdx);
}
parent[key] = this.references[refIdx];
}
}
_handleValue(val, parent, key) {
if (typeof val !== 'object' || val === null)
return;
const refIdx = val[CIRCULAR_REF_KEY];
if (refIdx !== void 0)
this._handleCircularRef(refIdx, parent, key);
else if (val[TRANSFORMED_TYPE_KEY])
this._handleTransformedObject(val, parent, key);
else if (Array.isArray(val)) {
for (let i = 0; i < val.length; i++)
this._handleValue(val[i], val, i);
}
else
this._handlePlainObject(val);
}
transform() {
this.visitedRefs[0] = true;
this._handleValue(this.references[0], this.references, 0);
return this.references[0];
}
}
// Transforms
const builtInTransforms = [
{
type: '[[NaN]]',
shouldTransform(type, val) {
return type === 'number' && isNaN(val);
},
toSerializable() {
return '';
},
fromSerializable() {
return NaN;
}
},
{
type: '[[undefined]]',
shouldTransform(type) {
return type === 'undefined';
},
toSerializable() {
return '';
},
fromSerializable() {
return void 0;
}
},
{
type: '[[Date]]',
shouldTransform(type, val) {
return val instanceof Date;
},
toSerializable(date) {
return date.getTime();
},
fromSerializable(val) {
const date = new Date();
date.setTime(val);
return date;
}
},
{
type: '[[RegExp]]',
shouldTransform(type, val) {
return val instanceof RegExp;
},
toSerializable(re) {
const result = {
src: re.source,
flags: ''
};
if (re.global)
result.flags += 'g';
if (re.ignoreCase)
result.flags += 'i';
if (re.multiline)
result.flags += 'm';
return result;
},
fromSerializable(val) {
return new RegExp(val.src, val.flags);
}
},
{
type: '[[Error]]',
shouldTransform(type, val) {
return val instanceof Error;
},
toSerializable(err) {
return {
name: err.name,
message: err.message,
stack: err.stack
};
},
fromSerializable(val) {
const Ctor = GLOBAL[val.name] || Error;
const err = new Ctor(val.message);
err.stack = val.stack;
return err;
}
},
{
type: '[[ArrayBuffer]]',
shouldTransform(type, val) {
return ARRAY_BUFFER_SUPPORTED && val instanceof ArrayBuffer;
},
toSerializable(buffer) {
const view = new Int8Array(buffer);
return arrSlice.call(view);
},
fromSerializable(val) {
if (ARRAY_BUFFER_SUPPORTED) {
const buffer = new ArrayBuffer(val.length);
const view = new Int8Array(buffer);
view.set(val);
return buffer;
}
return val;
}
},
{
type: '[[TypedArray]]',
shouldTransform(type, val) {
for (const ctorName of TYPED_ARRAY_CTORS) {
if (typeof GLOBAL[ctorName] === 'function' &&
val instanceof GLOBAL[ctorName])
return true;
}
return false;
},
toSerializable(arr) {
return {
ctorName: arr.constructor.name,
arr: arrSlice.call(arr)
};
},
fromSerializable(val) {
return typeof GLOBAL[val.ctorName] === 'function'
? new GLOBAL[val.ctorName](val.arr)
: val.arr;
}
},
{
type: '[[Map]]',
shouldTransform(type, val) {
return MAP_SUPPORTED && val instanceof Map;
},
toSerializable(map) {
const flattenedKVArr = [];
map.forEach((val, key) => {
flattenedKVArr.push(key);
flattenedKVArr.push(val);
});
return flattenedKVArr;
},
fromSerializable(val) {
if (MAP_SUPPORTED) {
// NOTE: new Map(iterable) is not supported by all browsers
const map = new Map();
for (var i = 0; i < val.length; i += 2)
map.set(val[i], val[i + 1]);
return map;
}
const kvArr = [];
// @ts-ignore
for (let j = 0; j < val.length; j += 2)
kvArr.push([val[i], val[i + 1]]);
return kvArr;
}
},
{
type: '[[Set]]',
shouldTransform(type, val) {
return SET_SUPPORTED && val instanceof Set;
},
toSerializable(set) {
const arr = [];
set.forEach((val) => {
arr.push(val);
});
return arr;
},
fromSerializable(val) {
if (SET_SUPPORTED) {
// NOTE: new Set(iterable) is not supported by all browsers
const set = new Set();
for (let i = 0; i < val.length; i++)
set.add(val[i]);
return set;
}
return val;
}
}
];
// Replicator
class Replicator {
constructor(serializer) {
this.transforms = [];
this.transformsMap = Object.create(null);
this.serializer = serializer || JSONSerializer;
this.addTransforms(builtInTransforms);
}
addTransforms(transforms) {
transforms = Array.isArray(transforms) ? transforms : [transforms];
for (const transform of transforms) {
if (this.transformsMap[transform.type])
throw new Error(`Transform with type "${transform.type}" was already added.`);
this.transforms.push(transform);
this.transformsMap[transform.type] = transform;
}
return this;
}
removeTransforms(transforms) {
transforms = Array.isArray(transforms) ? transforms : [transforms];
for (const transform of transforms) {
const idx = this.transforms.indexOf(transform);
if (idx > -1)
this.transforms.splice(idx, 1);
delete this.transformsMap[transform.type];
}
return this;
}
encode(val) {
const transformer = new EncodingTransformer(val, this.transforms);
const references = transformer.transform();
return this.serializer.serialize(references);
}
decode(val) {
const references = this.serializer.deserialize(val);
const transformer = new DecodingTransformer(references, this.transformsMap);
return transformer.transform();
}
}
export default Replicator;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvVHJhbnNmb3JtL3JlcGxpY2F0b3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsUUFBUTtBQUNSLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxDQUFBO0FBQ2pDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFBO0FBQzdCLE1BQU0sdUJBQXVCLEdBQUcsWUFBWSxDQUFBO0FBRTVDLE1BQU0sTUFBTSxHQUFHLENBQUMsU0FBUyxTQUFTO0lBQ2hDLDhGQUE4RjtJQUM5RixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUE7SUFFdEIsT0FBTyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDMUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtBQUVKLE1BQU0sc0JBQXNCLEdBQUcsT0FBTyxXQUFXLEtBQUssVUFBVSxDQUFBO0FBQ2hFLE1BQU0sYUFBYSxHQUFHLE9BQU8sR0FBRyxLQUFLLFVBQVUsQ0FBQTtBQUMvQyxNQUFNLGFBQWEsR0FBRyxPQUFPLEdBQUcsS0FBSyxVQUFVLENBQUE7QUFFL0MsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixXQUFXO0lBQ1gsWUFBWTtJQUNaLG1CQUFtQjtJQUNuQixZQUFZO0lBQ1osYUFBYTtJQUNiLFlBQVk7SUFDWixhQUFhO0lBQ2IsY0FBYztJQUNkLGNBQWM7Q0FDZixDQUFBO0FBRUQsd0JBQXdCO0FBQ3hCLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFBO0FBRXRDLHFCQUFxQjtBQUNyQixNQUFNLGNBQWMsR0FBRztJQUNyQixTQUFTLENBQUMsR0FBUTtRQUNoQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDNUIsQ0FBQztJQUVELFdBQVcsQ0FBQyxHQUFRO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN4QixDQUFDO0NBQ0Ys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