Skip to content

Commit 0982d2b

Browse files
authored
Fix support for proxying ArrayBuffer and SharedArrayBuffer (#112)
1 parent 0108e33 commit 0982d2b

4 files changed

Lines changed: 108 additions & 2 deletions

File tree

source/is-builtin.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ export function isBuiltinWithoutMutableMethods(value) {
1111
// Primitives and null → true. Functions → false. RegExp → true.
1212
return value === null
1313
|| (typeof value !== 'object' && typeof value !== 'function')
14-
|| value instanceof RegExp;
14+
|| value instanceof RegExp
15+
|| value instanceof ArrayBuffer
16+
|| (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer);
1517
}

tests/helpers/data-types.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ const typedArrays = [
8282
new Float64Array([1, 2, 3]),
8383
];
8484

85+
const arrayBuffers = [
86+
new ArrayBuffer(8),
87+
new SharedArrayBuffer(8),
88+
];
89+
8590
const nots = [undefined, null, Number.NaN];
8691

8792
const testValues = [
@@ -98,6 +103,7 @@ const testValues = [
98103
...weakSets,
99104
...weakMaps,
100105
...typedArrays,
106+
...arrayBuffers,
101107
];
102108

103109
export {
@@ -116,4 +122,5 @@ export {
116122
weakSets,
117123
weakMaps,
118124
typedArrays,
125+
arrayBuffers,
119126
};

tests/is-builtin.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import {
1515
weakSets,
1616
weakMaps,
1717
typedArrays,
18+
arrayBuffers,
1819
} from './helpers/data-types.js';
1920

20-
const withoutMutableMethods = [...nots, ...booleans, ...numbers, ...strings, ...regExps];
21+
const withoutMutableMethods = [...nots, ...booleans, ...numbers, ...strings, ...regExps, ...arrayBuffers];
2122
const singleCollections = [sets[0], maps[0], weakSets[0], weakMaps[0]];
2223

2324
for (const value of withoutMutableMethods) {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import test from 'ava';
2+
import onChange from '../source/index.js';
3+
4+
test('ArrayBuffer should not be proxied and byteLength should work', t => {
5+
const buffer = new ArrayBuffer(16);
6+
const object = {buffer};
7+
8+
let callCount = 0;
9+
const proxy = onChange(object, () => {
10+
callCount++;
11+
});
12+
13+
t.is(proxy.buffer.byteLength, 16);
14+
t.is(callCount, 0);
15+
});
16+
17+
test('SharedArrayBuffer should not be proxied and byteLength should work', t => {
18+
const buffer = new SharedArrayBuffer(24);
19+
const object = {buffer};
20+
21+
let callCount = 0;
22+
const proxy = onChange(object, () => {
23+
callCount++;
24+
});
25+
26+
t.is(proxy.buffer.byteLength, 24);
27+
t.is(callCount, 0);
28+
});
29+
30+
test('ArrayBuffer in nested object should work', t => {
31+
const buffer = new ArrayBuffer(32);
32+
const object = {
33+
nested: {
34+
data: {
35+
buffer,
36+
},
37+
},
38+
};
39+
40+
let callCount = 0;
41+
const proxy = onChange(object, () => {
42+
callCount++;
43+
});
44+
45+
t.is(proxy.nested.data.buffer.byteLength, 32);
46+
t.is(callCount, 0);
47+
});
48+
49+
test('ArrayBuffer should be returned as-is, not proxied', t => {
50+
const buffer = new ArrayBuffer(8);
51+
const object = {buffer};
52+
53+
const proxy = onChange(object, () => {});
54+
55+
t.is(proxy.buffer, buffer);
56+
});
57+
58+
test('Replacing ArrayBuffer should trigger onChange', t => {
59+
const buffer1 = new ArrayBuffer(8);
60+
const buffer2 = new ArrayBuffer(16);
61+
const object = {buffer: buffer1};
62+
63+
let callCount = 0;
64+
const proxy = onChange(object, () => {
65+
callCount++;
66+
});
67+
68+
proxy.buffer = buffer2;
69+
t.is(callCount, 1);
70+
t.is(proxy.buffer.byteLength, 16);
71+
});
72+
73+
test('TypedArray views should still be proxied', t => {
74+
const uint8 = new Uint8Array([1, 2, 3]);
75+
const object = {view: uint8};
76+
77+
let callCount = 0;
78+
const proxy = onChange(object, () => {
79+
callCount++;
80+
});
81+
82+
t.is(proxy.view.length, 3);
83+
t.is(proxy.view.byteLength, 3);
84+
85+
proxy.view[0] = 99;
86+
t.is(callCount, 1);
87+
});
88+
89+
test('ArrayBuffer from TypedArray.buffer should work', t => {
90+
const uint8 = new Uint8Array(16);
91+
const object = {view: uint8};
92+
93+
const proxy = onChange(object, () => {});
94+
95+
t.is(proxy.view.buffer.byteLength, 16);
96+
});

0 commit comments

Comments
 (0)