Like a cat leaving its mark
This package was heavily inspired by JSON and originally sought to fulfill 1 purpose which was to fit JSON payloads into Discord component custom IDs, so that the handlers for the component interactions could be stateless either to handle it themselves or to properly route the requests.
This package could be used on its own for totally unrelated things. The benefits of this is that a lot of the "extraneous" characters with JSON are removed and supports some features not supported by JSON. This includes undefined and BigInt.
The Object keys usually are surrounded by quotes, but just removing them saves a lot of space depending on how many entries are in your Object. If the encoded data is an Object, you can also totally ignore the first and last curly braces. This does mean that Arrays have 2 more characters which is to signify they are an Array.
encode({ thing: 2, but_also: "3", and_even: BigInt(1000) })
// turns into
'thing:2�but_also:"3�and_even:b1000' // is only 34 chars while in JSON (also turning the BigInt into a number or fail) is 42 chars
encode([2, "3", BigInt(1000)])
// turns into
'[2�"3�b1000]' // only ends up saving 1 char of space, but this is with a small Object. Bigger ones will see larger space savingsAlready, you can see a few tricks to save space, but what is that question mark symbol!? \uFFFD AKA The Replacement Character which is largely unused in text, but Scratch is smart enough to detect when it's present in strings and escape it and when decoding, only care about unescaped instances. It'll also unescape the text on decode so the return value is the same
Like JSON, it doesn't support circular references... Yet. Though the implementation idea I have to handle that would be a breaking change in the spec. It also doesn't support Symbols. Anything that supports calling Object.keys on it, it will support. Banned key names are prototype and proto because those can be used for attacks and we wouldn't really want that. Also similar to JSON, even if Objects are identical or even the same reference on encode, the reference gets lost on decode, but I think I can push that into the same solution as I would with circular references. If and when I decide to do that.