From de584b01a800e46ff62cfad9b32d67c8d26ce701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 21 Jan 2022 11:33:30 +0100 Subject: [PATCH] [FIX] reactivity: do not observe eventtarget and other stuff --- src/reactivity.ts | 17 +++++++++-------- tests/reactivity.test.ts | 13 +++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/reactivity.ts b/src/reactivity.ts index 4bb4aea7..c647e445 100644 --- a/src/reactivity.ts +++ b/src/reactivity.ts @@ -20,6 +20,7 @@ export type Reactive = T & { type NonReactive = T & { [SKIP]: any; }; +const objectToString = Object.prototype.toString; /** * Checks whether a given value can be made into a reactive object. @@ -28,14 +29,14 @@ type NonReactive = T & { * @returns whether the value can be made reactive */ function canBeMadeReactive(value: any): boolean { - return ( - typeof value === "object" && - value !== null && - !(value instanceof Date) && - !(value instanceof Promise) && - !(value instanceof String) && - !(value instanceof Number) - ); + if (typeof value !== "object") { + return false; + } + // extract "RawType" from strings like "[object RawType]" => this lets us + // ignore many native objects such as Promise (whose toString is [object Promise]) + // or Date ([object Date]). + const rawType = objectToString.call(value).slice(8, -1); + return rawType === "Object" || rawType === "Array"; } /** diff --git a/tests/reactivity.test.ts b/tests/reactivity.test.ts index 8dd91050..35b1e453 100644 --- a/tests/reactivity.test.ts +++ b/tests/reactivity.test.ts @@ -1093,6 +1093,19 @@ describe("Reactivity", () => { expect(n).toBe(1); expect(state.k).toEqual({ n: 2 }); }); + + test("can add collections set/weakset/map/weakmap in a reactive object", () => { + const rawSet = new Set(); + const rawWeakSet = new WeakSet(); + const rawMap = new Map(); + const rawWeakMap = new WeakMap(); + + const obj = reactive({ rawSet, rawWeakSet, rawMap, rawWeakMap }); + expect(obj.rawSet).toBe(rawSet); + expect(obj.rawWeakSet).toBe(rawWeakSet); + expect(obj.rawMap).toBe(rawMap); + expect(obj.rawWeakMap).toBe(rawWeakMap); + }); }); describe("markRaw", () => {