From 82f5bfb7ea8ef292607eb888aab8dec8fa453823 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Mon, 19 Dec 2022 18:32:52 +0100 Subject: [PATCH] Shorten the serialization of lists This also helps prevent stack overflows when JSON.stringify large Elm lists. --- lib/result-cache-json.js | 63 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/result-cache-json.js b/lib/result-cache-json.js index 5290e1046..2a30dc76e 100644 --- a/lib/result-cache-json.js +++ b/lib/result-cache-json.js @@ -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'; } @@ -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$$') ) { @@ -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; +}