simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

map.js (3129B)


      1 import { setSafeProperty, hasSafeProperty, getSafeProperty } from './customs.js';
      2 import { isObject } from './is.js';
      3 /**
      4  * A map facade on a bare object.
      5  *
      6  * The small number of methods needed to implement a scope,
      7  * forwarding on to the SafeProperty functions. Over time, the codebase
      8  * will stop using this method, as all objects will be Maps, rather than
      9  * more security prone objects.
     10  */
     11 
     12 export class ObjectWrappingMap {
     13   constructor(object) {
     14     this.wrappedObject = object;
     15   }
     16 
     17   keys() {
     18     return Object.keys(this.wrappedObject);
     19   }
     20 
     21   get(key) {
     22     return getSafeProperty(this.wrappedObject, key);
     23   }
     24 
     25   set(key, value) {
     26     setSafeProperty(this.wrappedObject, key, value);
     27     return this;
     28   }
     29 
     30   has(key) {
     31     return hasSafeProperty(this.wrappedObject, key);
     32   }
     33 
     34 }
     35 /**
     36  * Creates an empty map, or whatever your platform's polyfill is.
     37  *
     38  * @returns an empty Map or Map like object.
     39  */
     40 
     41 export function createEmptyMap() {
     42   return new Map();
     43 }
     44 /**
     45  * Creates a Map from the given object.
     46  *
     47  * @param { Map | { [key: string]: unknown } | undefined } mapOrObject
     48  * @returns
     49  */
     50 
     51 export function createMap(mapOrObject) {
     52   if (!mapOrObject) {
     53     return createEmptyMap();
     54   }
     55 
     56   if (isMap(mapOrObject)) {
     57     return mapOrObject;
     58   }
     59 
     60   if (isObject(mapOrObject)) {
     61     return new ObjectWrappingMap(mapOrObject);
     62   }
     63 
     64   throw new Error('createMap can create maps from objects or Maps');
     65 }
     66 /**
     67  * Unwraps a map into an object.
     68  *
     69  * @param {Map} map
     70  * @returns { [key: string]: unknown }
     71  */
     72 
     73 export function toObject(map) {
     74   if (map instanceof ObjectWrappingMap) {
     75     return map.wrappedObject;
     76   }
     77 
     78   var object = {};
     79 
     80   for (var key of map.keys()) {
     81     var value = map.get(key);
     82     setSafeProperty(object, key, value);
     83   }
     84 
     85   return object;
     86 }
     87 /**
     88  * Returns `true` if the passed object appears to be a Map (i.e. duck typing).
     89  *
     90  * Methods looked for are `get`, `set`, `keys` and `has`.
     91  *
     92  * @param {Map | object} object
     93  * @returns
     94  */
     95 
     96 export function isMap(object) {
     97   // We can use the fast instanceof, or a slower duck typing check.
     98   // The duck typing method needs to cover enough methods to not be confused with DenseMatrix.
     99   if (!object) {
    100     return false;
    101   }
    102 
    103   return object instanceof Map || object instanceof ObjectWrappingMap || typeof object.set === 'function' && typeof object.get === 'function' && typeof object.keys === 'function' && typeof object.has === 'function';
    104 }
    105 /**
    106  * Copies the contents of key-value pairs from each `objects` in to `map`.
    107  *
    108  * Object is `objects` can be a `Map` or object.
    109  *
    110  * This is the `Map` analog to `Object.assign`.
    111  */
    112 
    113 export function assign(map) {
    114   for (var _len = arguments.length, objects = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    115     objects[_key - 1] = arguments[_key];
    116   }
    117 
    118   for (var args of objects) {
    119     if (!args) {
    120       continue;
    121     }
    122 
    123     if (isMap(args)) {
    124       for (var key of args.keys()) {
    125         map.set(key, args.get(key));
    126       }
    127     } else if (isObject(args)) {
    128       for (var _key2 of Object.keys(args)) {
    129         map.set(_key2, args[_key2]);
    130       }
    131     }
    132   }
    133 
    134   return map;
    135 }