Adaptive Notation for JSON

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Adaptive Notation for JSON

Anders Rundgren-2
Trying again...

It turned out that the Oracle/Java JSON API actually is I-JSON compatible by default through a method which I have coined "Adaptive Notation":

{
    "BigDecimal.large": "1E+999",
    "BigDecimal.small": 1,
    "BigInteger.large": "240777489003222785532321",
    "BigInteger.small": 1,
    "Long.large": "9223372036854775807",
    "Long.small": 1
}

Personally I prefer schemes where you either use JSON Number or JSON String, rather than mixing these depending on the actual value.

However, the most important is finding a common solution.

WDYT?

Anders
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Adaptive Notation for JSON

Andrea Giammarchi-2
My 2 cents.

For classes with a reachable namespace from the window / global and serializable arguments, you could use an ad-hoc structure to define complex values:

```js
// the converter
const toJSONStruct = value =>
  Object.defineProperty(
    {
      "arguments": Symbol.iterator in value ?
                    [[...value]] :
                    [value.valueOf()]
    },
    "__proto__",
    {
      enumerable: true,
      value: value.constructor.name
    }
  );

// the replacer (basic example)
const replacer = (key, value) => {
  if (
    typeof value === 'object' &&
    value &&
    !/^(?:Array|Object)$/.test(value.constructor.name)
  ) return toJSONStruct(value);
  return value;
};
```

Here how you can produce some JSON
```js
// example of a complex value
JSON.stringify(
  {
    property: new Uint8Array([10, 20, 30])
  },
  replacer,
  '  '
);

/*
{
  "property": {
    "arguments": [
      [
        10,
        20,
        30
      ]
    ],
    "__proto__": "Uint8Array"
  }
}
*/
```

A revirer example:

```js
const reviver = (key, value) => {
  if (
    typeof value === 'object' &&
    value !== null &&
    value.hasOwnProperty('__proto__')
  ) {
    const Class = value.__proto__
                        .split('.')
                        .reduce((O, K) => O[K], window);
    return new Class(...value.arguments);
  }
  return value;
};
```

and a quick proof of the demo:
```js
console.log(
  JSON.parse(
    `{
      "property": {
        "arguments": [
          [
            10,
            20,
            30
          ]
        ],
        "__proto__": "Uint8Array"
      }
    }`,
    reviver
  )
);
```

Having this standardized, since it's very unlikely anyone would use `__proto__` key for a different reason, seems like an easier way to reason about complex serialized values.

Having `toJSON` and or `toJSONConstructor` able to return such struct instead of needing `toJSONStruct` would be even better.

Best Regards


On Sat, May 19, 2018 at 7:05 AM, Anders Rundgren <[hidden email]> wrote:
Trying again...

It turned out that the Oracle/Java JSON API actually is I-JSON compatible by default through a method which I have coined "Adaptive Notation":

{
   "BigDecimal.large": "1E+999",
   "BigDecimal.small": 1,
   "BigInteger.large": "240777489003222785532321",
   "BigInteger.small": 1,
   "Long.large": "9223372036854775807",
   "Long.small": 1
}

Personally I prefer schemes where you either use JSON Number or JSON String, rather than mixing these depending on the actual value.

However, the most important is finding a common solution.

WDYT?

Anders
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss