diff --git a/packages/relay-runtime/util/__tests__/deepFreeze-test.js b/packages/relay-runtime/util/__tests__/deepFreeze-test.js index 64173eb1fa676..acee4803f06e6 100644 --- a/packages/relay-runtime/util/__tests__/deepFreeze-test.js +++ b/packages/relay-runtime/util/__tests__/deepFreeze-test.js @@ -53,4 +53,10 @@ describe('deepFreeze()', () => { it('copes with null values', () => { expect(deepFreeze({a: null})).toBeFrozen(); }); + + it('does not throw on array buffers', () => { + const x = new Uint16Array([21, 31]); + expect(() => deepFreeze(x)).not.toThrow(); + expect(() => deepFreeze({x})).not.toThrow(); + }); }); diff --git a/packages/relay-runtime/util/deepFreeze.js b/packages/relay-runtime/util/deepFreeze.js index 6fcd355e02a38..80a8370e6c653 100644 --- a/packages/relay-runtime/util/deepFreeze.js +++ b/packages/relay-runtime/util/deepFreeze.js @@ -18,6 +18,9 @@ * returns the now-frozen original object. */ function deepFreeze(object: T): T { + if (!shouldBeFrozen(object)) { + return object; + } Object.freeze(object); Object.getOwnPropertyNames(object).forEach(name => { const property = object[name]; @@ -32,4 +35,18 @@ function deepFreeze(object: T): T { return object; } +function shouldBeFrozen(value: mixed): boolean { + // Primitives and functions: + if (value === null || typeof value !== 'object') { + return false; + } + + // Views on array buffers cannot be frozen + if (ArrayBuffer.isView(value)) { + return false; + } + + return true; +} + module.exports = deepFreeze;