I've written so many serializer/encoder/decoder but I feel like going back to basics every single time, although this time I think I've nailed a prototype that works well with both native JSON API and flatted, downloaded 500M+ per month these days (signaling JSON is still the most used serializer out there, despite its age and caveats).
JSONRegistry is identical to JSON except it allows users to define a registry payload:
const { parse, stringify } = new JSONRegistry([
['Uint8Array', {
is: value => value instanceof Uint8Array,
to: value => Array.from(value),
from: value => Uint8Array.from(value),
}],
]);
parse(stringify(new Uint8Array([1, 2, 3])));
// it's a Uint8Array reference
How does it work?
It basically uses a well known type such as array to push the desired transformed type, where types must be unique strings (it throws on duplicated types like any registry). The reason it does that is to both KISS and have the ability to revive types at the other end, something toJSON is not capable of, something every other serializer does in a way or another as both binary format or string to unserialize.
The bonus types can be configured (that is bigint or symbol as value) if desired, these are the only primitive that would not work out of the box but, if not registered, these throw like these would within regular JSON.
Why do we need it?
There are various similar topics where developers want "this type or that one" embedded natively (it does not scale well) or special Symbol.toJSON which cannot have a Symbol.fromJSON counterpart because incompatible with JSON standard itself, other ideas that try to workaround structuredClone or JSON limitations but there's literally nothing concrete to consider/move forward, imho.
This idea solves:
- it puts exotic types on developers shoulder but it uses regular JSON API transparently
- it's compatible out of the box with JSON, nothing changes at its standard level
- it helps projects share a well known/defined payload
- it throws as soon as things are not registered or not sound, just like
symbolorbigintwould already - it allows engines to optimize at their core for performance boost with a logic that is very straight forward
I hope the prototype and this thread could at least start some sort of conversation so thanks in advance to whoever is interested into having that conversation ![]()