86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import {
 | |
|   VOID, PRIMITIVE,
 | |
|   ARRAY, OBJECT,
 | |
|   DATE, REGEXP, MAP, SET,
 | |
|   ERROR, BIGINT
 | |
| } from './types.js';
 | |
| 
 | |
| const env = typeof self === 'object' ? self : globalThis;
 | |
| 
 | |
| const deserializer = ($, _) => {
 | |
|   const as = (out, index) => {
 | |
|     $.set(index, out);
 | |
|     return out;
 | |
|   };
 | |
| 
 | |
|   const unpair = index => {
 | |
|     if ($.has(index))
 | |
|       return $.get(index);
 | |
| 
 | |
|     const [type, value] = _[index];
 | |
|     switch (type) {
 | |
|       case PRIMITIVE:
 | |
|       case VOID:
 | |
|         return as(value, index);
 | |
|       case ARRAY: {
 | |
|         const arr = as([], index);
 | |
|         for (const index of value)
 | |
|           arr.push(unpair(index));
 | |
|         return arr;
 | |
|       }
 | |
|       case OBJECT: {
 | |
|         const object = as({}, index);
 | |
|         for (const [key, index] of value)
 | |
|           object[unpair(key)] = unpair(index);
 | |
|         return object;
 | |
|       }
 | |
|       case DATE:
 | |
|         return as(new Date(value), index);
 | |
|       case REGEXP: {
 | |
|         const {source, flags} = value;
 | |
|         return as(new RegExp(source, flags), index);
 | |
|       }
 | |
|       case MAP: {
 | |
|         const map = as(new Map, index);
 | |
|         for (const [key, index] of value)
 | |
|           map.set(unpair(key), unpair(index));
 | |
|         return map;
 | |
|       }
 | |
|       case SET: {
 | |
|         const set = as(new Set, index);
 | |
|         for (const index of value)
 | |
|           set.add(unpair(index));
 | |
|         return set;
 | |
|       }
 | |
|       case ERROR: {
 | |
|         const {name, message} = value;
 | |
|         return as(new env[name](message), index);
 | |
|       }
 | |
|       case BIGINT:
 | |
|         return as(BigInt(value), index);
 | |
|       case 'BigInt':
 | |
|         return as(Object(BigInt(value)), index);
 | |
|       case 'ArrayBuffer':
 | |
|         return as(new Uint8Array(value).buffer, value);
 | |
|       case 'DataView': {
 | |
|         const { buffer } = new Uint8Array(value);
 | |
|         return as(new DataView(buffer), value);
 | |
|       }
 | |
|     }
 | |
|     return as(new env[type](value), index);
 | |
|   };
 | |
| 
 | |
|   return unpair;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @typedef {Array<string,any>} Record a type representation
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * Returns a deserialized value from a serialized array of Records.
 | |
|  * @param {Record[]} serialized a previously serialized value.
 | |
|  * @returns {any}
 | |
|  */
 | |
| export const deserialize = serialized => deserializer(new Map, serialized)(0);
 |