Skip to content

Commit

Permalink
[New] support cloning Typed Arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
scagood authored and ljharb committed Aug 22, 2023
1 parent f5a3724 commit 18c32c5
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 12 deletions.
12 changes: 11 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
},
}
],
}
32 changes: 22 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
'use strict';

var whichTypedArray = require('which-typed-array');
var taSlice = require('typedarray.prototype.slice');

// 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]'; }
Expand Down Expand Up @@ -68,17 +71,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) {
return taSlice(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) {
Expand Down Expand Up @@ -287,6 +295,10 @@ Traverse.prototype.clone = function () {
var parents = [];
var nodes = [];

if (whichTypedArray(this.value)) {
return taSlice(this.value);
}

return (function clone(src) {
for (var i = 0; i < parents.length; i++) {
if (parents[i] === src) {
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
".github/workflows"
]
},
"dependencies": {
"typedarray.prototype.slice": "^1.0.1",
"which-typed-array": "^1.1.11"
},
"engines": {
"node": ">= 0.4"
}
Expand Down
18 changes: 17 additions & 1 deletion test/mutability.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ test('cloneT', function (t) {
t.end();
});

test('cloneTypedArray', { skip: typeof Uint8Array !== 'function' }, function (t) {
var obj = new Uint8Array([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, new Uint8Array([2]));
t.same(res, new Uint8Array([3]));
t.end();
});

test('reduce', function (t) {
var obj = { a: 1, b: 2, c: [3, 4] };
var res = traverse(obj).reduce(function (acc, x) {
Expand Down Expand Up @@ -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] }));
Expand All @@ -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] }));

Expand All @@ -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();
Expand Down
12 changes: 12 additions & 0 deletions test/typed-array.js
Original file line number Diff line number Diff line change
@@ -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 = new Uint8Array(4);
var results = traverse(obj).map(function () {});
t.same(results, obj);
t.end();
});

0 comments on commit 18c32c5

Please sign in to comment.