Skip to content

Commit

Permalink
Shorten the serialization of lists
Browse files Browse the repository at this point in the history
This also helps prevent stack overflows when JSON.stringify large Elm
lists.
  • Loading branch information
jfmengels committed Dec 19, 2022
1 parent 28a1a11 commit 82f5bfb
Showing 1 changed file with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion lib/result-cache-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,34 @@ module.exports = {
};

function replacer(key, value) {
if (typeof value === 'object') {
// TODO Serialize Dicts also
// if (value.$ === -1) {
// return {
// $: '$D',
// a: toDictProd(value, {})
// };
// }
if (
value.$ === 1 &&
value.a !== undefined &&
value.b !== undefined &&
value.c === undefined
) {
const list = prudent_List_toArray(value);
if (list === null) {
return value;
}

return {
$: '$L',
a: list
};
}

return value;
}

if (Number.isNaN(value)) {
return '$$elm-review$$NaN';
}
Expand All @@ -19,9 +47,32 @@ function replacer(key, value) {
return '$$elm-review$$+Inf';
}


function prudent_List_toArray(xs) {
const out = [];
for (; xs.b; xs = xs.b) {
if (xs.a === undefined || xs.c !== undefined) {
return null;
}

out.push(xs.a);
}

if (xs.$ !== 0 || xs.a !== undefined) {
return null;
}

return out;
}

function reviver(_, value) {
const type_ = typeof value;
if (type_ === 'object' && value.$ === '$L') {
return _List_fromArray_PROD(value.a);
}

if (
typeof value !== 'string' ||
type_ !== 'string' ||
value === null ||
!value.startsWith('$$elm-review$$')
) {
Expand All @@ -39,3 +90,13 @@ function reviver(_, value) {
return value;
}
}

const _List_Nil_PROD = {$: 0};
function _List_fromArray_PROD(array) {
let out = _List_Nil_PROD;
for (let i = array.length; i--; ) {
out = {$: 1, a: array[i], b: out};
}

return out;
}

0 comments on commit 82f5bfb

Please sign in to comment.