diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-06-28 12:38:34 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-28 12:38:34 -0400 | 
| commit | cdf191336aa616a206b977ba3beeb1233cf41c32 (patch) | |
| tree | 07df9e5eec80dd4379c7ed97854a2bd9ef5149eb /ext/mixed/js | |
| parent | 5bf805755a33f6f10fd9621f8a2bff7ba1cb7440 (diff) | |
Clone function (#624)
* Add clone function
* Replace utilIsolate with clone
* Replace JsonSchema.isolate with clone function
* Include core.js for tests which use json-schema.js
* Update visisted set
Diffstat (limited to 'ext/mixed/js')
| -rw-r--r-- | ext/mixed/js/core.js | 67 | 
1 files changed, 67 insertions, 0 deletions
| diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js index 21b7bf5e..9b3ea3e2 100644 --- a/ext/mixed/js/core.js +++ b/ext/mixed/js/core.js @@ -157,6 +157,73 @@ function getSetDifference(set1, set2) {      );  } +const clone = (() => { +    // eslint-disable-next-line no-shadow +    function clone(value) { +        if (value === null) { return null; } +        switch (typeof value) { +            case 'boolean': +            case 'number': +            case 'string': +            case 'bigint': +            case 'symbol': +            case 'undefined': +                return value; +            default: +                return cloneInternal(value, new Set()); +        } +    } + +    function cloneInternal(value, visited) { +        if (value === null) { return null; } +        switch (typeof value) { +            case 'boolean': +            case 'number': +            case 'string': +            case 'bigint': +            case 'symbol': +            case 'undefined': +                return value; +            case 'function': +                return cloneObject(value, visited); +            case 'object': +                return Array.isArray(value) ? cloneArray(value, visited) : cloneObject(value, visited); +        } +    } + +    function cloneArray(value, visited) { +        if (visited.has(value)) { throw new Error('Circular'); } +        try { +            visited.add(value); +            const result = []; +            for (const item of value) { +                result.push(cloneInternal(item, visited)); +            } +            return result; +        } finally { +            visited.delete(value); +        } +    } + +    function cloneObject(value, visited) { +        if (visited.has(value)) { throw new Error('Circular'); } +        try { +            visited.add(value); +            const result = {}; +            for (const key in value) { +                if (Object.prototype.hasOwnProperty.call(value, key)) { +                    result[key] = cloneInternal(value[key], visited); +                } +            } +            return result; +        } finally { +            visited.delete(value); +        } +    } + +    return clone; +})(); +  /*   * Async utilities |