You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.8 KiB
54 lines
1.8 KiB
/** |
|
* Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec, |
|
* in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the |
|
* 2021 edition: https://tc39.es/ecma262/#sec-json.parse |
|
* |
|
* Includes extensions for handling Map and Set objects. |
|
*/ |
|
function applyReviver(reviver, obj, key, val) { |
|
if (val && typeof val === 'object') { |
|
if (Array.isArray(val)) { |
|
for (let i = 0, len = val.length; i < len; ++i) { |
|
const v0 = val[i]; |
|
const v1 = applyReviver(reviver, val, String(i), v0); |
|
if (v1 === undefined) |
|
delete val[i]; |
|
else if (v1 !== v0) |
|
val[i] = v1; |
|
} |
|
} |
|
else if (val instanceof Map) { |
|
for (const k of Array.from(val.keys())) { |
|
const v0 = val.get(k); |
|
const v1 = applyReviver(reviver, val, k, v0); |
|
if (v1 === undefined) |
|
val.delete(k); |
|
else if (v1 !== v0) |
|
val.set(k, v1); |
|
} |
|
} |
|
else if (val instanceof Set) { |
|
for (const v0 of Array.from(val)) { |
|
const v1 = applyReviver(reviver, val, v0, v0); |
|
if (v1 === undefined) |
|
val.delete(v0); |
|
else if (v1 !== v0) { |
|
val.delete(v0); |
|
val.add(v1); |
|
} |
|
} |
|
} |
|
else { |
|
for (const [k, v0] of Object.entries(val)) { |
|
const v1 = applyReviver(reviver, val, k, v0); |
|
if (v1 === undefined) |
|
delete val[k]; |
|
else if (v1 !== v0) |
|
val[k] = v1; |
|
} |
|
} |
|
} |
|
return reviver.call(obj, key, val); |
|
} |
|
|
|
export { applyReviver };
|
|
|