From 99a6142a3799e5a470f2b1d246653a9baf1977a7 Mon Sep 17 00:00:00 2001 From: Sebastian Good <2230835+scagood@users.noreply.github.com> Date: Tue, 22 Aug 2023 22:30:19 +0300 Subject: [PATCH] [New] support cloning Typed Arrays --- .eslintrc | 12 +++++++++++- index.js | 27 +++++++++++++++++---------- package.json | 3 +++ test/mutability.js | 18 +++++++++++++++++- test/typed-array.js | 12 ++++++++++++ 5 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 test/typed-array.js diff --git a/.eslintrc b/.eslintrc index d8824e9..30de5dd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,7 +11,7 @@ "func-style": [2, "declaration"], "global-require": 1, "max-lines-per-function": 0, - "max-statements-per-line": 1, + "max-statements-per-line": [1, {"max": 2}], "multiline-comment-style": 0, "no-proto": 0, "no-sparse-arrays": 1, @@ -27,7 +27,17 @@ "rules": { "no-console": 0, "no-plusplus": 0, + "no-magic-numbers": 0, }, }, + { + "files": [ + "test/typed-array.js", + "test/mutability.js", + ], + "globals": { + "Uint8Array": false + }, + } ], } diff --git a/index.js b/index.js index 256a700..59e0108 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,7 @@ 'use strict'; +var whichTypedArray = require('which-typed-array'); + // TODO: use call-bind, is-date, is-regex, is-string, is-boolean-object, is-number-object function toS(obj) { return Object.prototype.toString.call(obj); } function isDate(obj) { return toS(obj) === '[object Date]'; } @@ -68,17 +70,22 @@ function copy(src) { dst = { message: src.message }; } else if (isBoolean(src) || isNumber(src) || isString(src)) { dst = Object(src); - } else if (Object.create && Object.getPrototypeOf) { - dst = Object.create(Object.getPrototypeOf(src)); - } else if (src.constructor === Object) { - dst = {}; } else { - var proto = (src.constructor && src.constructor.prototype) - || src.__proto__ - || {}; - var T = function T() {}; // eslint-disable-line func-style, func-name-matching - T.prototype = proto; - dst = new T(); + var ta = whichTypedArray(src); + if (ta) { + dst = global[ta].from(src); + } else if (Object.create && Object.getPrototypeOf) { + dst = Object.create(Object.getPrototypeOf(src)); + } else if (src.constructor === Object) { + dst = {}; + } else { + var proto = (src.constructor && src.constructor.prototype) + || src.__proto__ + || {}; + var T = function T() {}; // eslint-disable-line func-style, func-name-matching + T.prototype = proto; + dst = new T(); + } } forEach(ownEnumerableKeys(src), function (key) { diff --git a/package.json b/package.json index 4c2c290..c4b7930 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,9 @@ ".github/workflows" ] }, + "dependencies": { + "which-typed-array": "^1.1.11" + }, "engines": { "node": ">= 0.4" } diff --git a/test/mutability.js b/test/mutability.js index dc5d6f4..3179639 100644 --- a/test/mutability.js +++ b/test/mutability.js @@ -77,6 +77,19 @@ test('cloneT', function (t) { t.end(); }); +test('cloneTypedArray', { skip: typeof Uint8Array !== 'function' }, function (t) { + var obj = Uint8Array.from([1]); + var res = traverse.clone(obj); + + t.same(obj, res); + t.ok(obj !== res); + obj.set([2], 0); + res.set([3], 0); + t.same(obj, Uint8Array.from([2])); + t.same(res, Uint8Array.from([3])); + t.end(); +}); + test('reduce', function (t) { var obj = { a: 1, b: 2, c: [3, 4] }; var res = traverse(obj).reduce(function (acc, x) { @@ -194,6 +207,7 @@ test('deleteRedux', function (t) { t.ok(!deepEqual(obj, { a: 1, c: [3, undefined, 5] })); + // eslint-disable-next-line no-sparse-arrays t.ok(deepEqual(obj, { a: 1, c: [3,, 5] })); t.ok(!deepEqual(obj, { a: 1, c: [3, null, 5] })); @@ -219,7 +233,8 @@ test('deleteMap', function (t) { t.ok(deepEqual(res, { a: 1, c: xs })); - t.ok(deepEqual(res, { a: 1, c: [3,,] })); // eslint-disable-line comma-spacing + // eslint-disable-next-line comma-spacing, no-sparse-arrays + t.ok(deepEqual(res, { a: 1, c: [3,,] })); t.ok(deepEqual(res, { a: 1, c: [3] })); @@ -244,6 +259,7 @@ test('deleteMapRedux', function (t) { t.ok(!deepEqual(res, { a: 1, c: [3, 5] })); + // eslint-disable-next-line no-sparse-arrays t.ok(deepEqual(res, { a: 1, c: [3,, 5] })); t.end(); diff --git a/test/typed-array.js b/test/typed-array.js new file mode 100644 index 0000000..743617f --- /dev/null +++ b/test/typed-array.js @@ -0,0 +1,12 @@ +'use strict'; + +var test = require('tape'); +var traverse = require('../'); + +test('traverse an UInt8Array', { skip: typeof Uint8Array !== 'function' }, function (t) { + var obj = Uint8Array.from('test'); + var results = traverse(obj).map(function () {}); + t.same(results, obj); + t.end(); +}); +