Skip to content

Latest commit

 

History

History
284 lines (202 loc) · 8.79 KB

LEEME.md

File metadata and controls

284 lines (202 loc) · 8.79 KB

json4all

JSON para todos los propósitos y todas las plataformas

stable npm-version downloads build coverage dependencies

idioma: castellano también disponible en: inglés

Instalación

$ npm install json4all

Objetivo

Reemplazar JSON por una función que

  • pueda codificar/decodificar:
    • Fechas del tipo nativo Date
    • Expresiones regulares del tipo Regexp
    • Objetos y arreglos que contengan undefined
    • Tipos definidos por el usuario
  • sea seguro, o sea no codifique funciones (Function)
  • tenga un mecanismo para intercambiar objetos entre el frontend y el backend que:
    • Envíe al frontend una copia del objeto que tenga solo las propiedades que correponda, para esconder la implementación o información que no debe salir del backend
    • Envíe al frontend una referencia de objeto que permita identificar la instancia precisa dentro del backend. Así el frontend recibe una copia de las propiedades que correspondan y un modo de identificar al objeto preciso del backend.
var JSON4all = require('json4all');

var today = new Date();
var tansDate = JSON4all.parse(JSON4all.stringify(today));
console.log(transDate.constructor.name); // Date

JSON4all.addType(Constructor)

Registra la clase definida por el constructor.

La clase debe tener definidas las funciones:

  • JSON4replacer (a nivel de la instancia de objeto o del prototipo) que devuelve un valor que sirve para recrear el objeto
  • JSON4reviver (a nivel de la clase) que recive el valor para recrear el objeto y devuelve el nuevo objeto recreado
var JSON4all = require('json4all');

function Point(x, y, z) {
    this.klass = 'Point';
    this.x     = x;
    this.y     = y;
    this.z     = z;
}

Point.prototype.JSON4replacer=function(){ return {x:this.x, y:this.y, z:this.z}; }
Point.JSON4reviver=function(o){ return new Point(o.x, o.y, o.z); }

JSON4all.addType(Point);

var p = new Point();
var q = JSON4all.parse(JSON4all.stingify(p));

console.log(q instanceof Point); // true

@JSON4all.addClass

Decorator que registra la clase definida.

Se deben indicar qué propiedades deben serializarse con addProperty. Cuando una propiedad es parámetro del constructor principal de la clase hay que indicar el orden (comenzando en 1) con addProperty(n)

var JSON4all = require('json4all');

@JSON4all.addClass
class Point {
    @JSON4all.addProperty(1) public x: number
    @JSON4all.addProperty(2) public y: number
    @JSON4all.addProperty(3) public z: number
    @JSON4all.addProperty public color: string | undefined
    public internal: number | undefined
    constructor(x, y, z){
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

var p = new Point(1.1, 2.3, 3.14);
p.internal = 7;

var q = JSON4all.parse(JSON4all.stingify(p));

console.log(q.internal); // undefined
console.log(q instanceof Point); // true
console.log(q.z); // 3.14

JSON4all.RefStore

Registra un objeto como repositorio de instancias referenciables en el backend y copias en el frontend (las modificación copias en el frontend no impactan en el backend).

Cuando el objeto es serializado en el backend se le agrega una referencia. Al llegar al frontend el objeto es revivido y conservada la referencia.

Cuando el objeto se envía del backend al frontend, al serializarlo solo se envía la referencia (porque al ser una copia no es necesario pasar los datos porque ya están en el backend)

// in the back-end
import * as JSON4all from 'json4all';
import { Point } from './common/my-classes';

JSON4all.RefStoreSpace(global.mySpace)

var points = JSON4all.RefStore<string, Point>(['points']);

var center = new Point(100,200,-50);
points['x3298484'] = center;

console.log(points[JSON4all.RefKey]) // 'x3298484'
var str = JSON4all.stringify(center);

var center2 = JSON4all.parse(str);

console.log( center === center2 ); // true the same instance!!!!

res.send(JSON4all.stringify(center));

// IN THE FRONT-END:
import * as JSON4all from 'json4all';
import { Point } from './common/my-classes';

var pointStr = await simpleFetch('https://..../center')
var point = JSON4all.parse()

console.log(point.x, point.y, point.z); // 100,200,-50
point.x = 999;

simpleFetch('https://..../set-center?point='+JSON4all.stringify(point));
// only the ref is sended

// IN THE BACK-END:

app.get('/set-center',(req)=>{
    // with the ref the object is retrived from the collection
    var point = JSON4all.parse(req.query('point'));
    console.log(point.x, point.y, point.z); // 100,200,-50
    console.log(points['x3298484'] === point) // the same instance
})

JSON4all.pretendClass(object, classConstructor)

Interviene un objeto plano para que la llamada a JSON.stringify(object) devuelva el mismo valor que la llamada a una instancia de clase que tenga sus mismos valores (JSON.stringify(object) === JSON.object(instance)).

var point = new Point({x:7, y:8});
var object = {x:7, y:8};

JSON4all.pretendClass(object, Point);

console.log(JSON4all.stringify(object) == JSON4all.stringify(point)); // true

var restoredPoint = JSON4all.parse(JSON4all.stringify(object));

console.log(restoredPoint instanceof Point); // true

Pruebas con dispositivos reales

NPM version Device OS nav
0.1.4 Samsung SM-T560 Android 4.4.4 Firefox 49.0.0
0.1.4 Samsung SM-T560 Android 4.4.4 Chrome 53.0.2785
0.1.4 Samsung SM-T560 Android 4.4.4 Opera 37.0.2192
0.1.4 Samsung S5 Android 4.4.2 Firefox 49.0.0
0.1.4 Samsung S5 Android 4.4.2 Opera Mobile 37.1.2192

Licencia

MIT