diff --git a/src/runtime/reactivity.ts b/src/runtime/reactivity.ts index ffe33493..19610535 100644 --- a/src/runtime/reactivity.ts +++ b/src/runtime/reactivity.ts @@ -28,7 +28,7 @@ const COLLECTION_RAWTYPES = new Set(["Set", "Map", "WeakMap"]); * @returns the raw type of the object */ function rawType(obj: any) { - return objectToString.call(obj).slice(8, -1); + return objectToString.call(toRaw(obj)).slice(8, -1); } /** * Checks whether a given value can be made into a reactive object. diff --git a/tests/reactivity.test.ts b/tests/reactivity.test.ts index a02648fa..9d67f1d5 100644 --- a/tests/reactivity.test.ts +++ b/tests/reactivity.test.ts @@ -9,7 +9,7 @@ import { markRaw, toRaw, } from "../src"; -import { reactive } from "../src/runtime/reactivity"; +import { reactive, getSubscriptions } from "../src/runtime/reactivity"; import { batched } from "../src/runtime/utils"; import { makeDeferred, @@ -1020,6 +1020,32 @@ describe("Reactivity", () => { expect(n3).toBe(2); }); + test("reactive inside other: reading the inner reactive from outer doesn't affect the inner's subscriptions", async () => { + const getObservedKeys = (obj: any) => getSubscriptions(obj).flatMap(({ keys }) => keys); + let n1 = 0; + let n2 = 0; + const innerCb = () => n1++; + const outerCb = () => n2++; + const inner = createReactive({ a: 1 }, innerCb); + const outer = createReactive({ b: inner }, outerCb); + expect(n1).toBe(0); + expect(n2).toBe(0); + expect(getObservedKeys(innerCb)).toEqual([]); + expect(getObservedKeys(outerCb)).toEqual([]); + + outer.b.a; + expect(getObservedKeys(innerCb)).toEqual([]); + expect(getObservedKeys(outerCb)).toEqual(["b", "a"]); + expect(n1).toBe(0); + expect(n2).toBe(0); + + outer.b.a = 2; + expect(getObservedKeys(innerCb)).toEqual([]); + expect(getObservedKeys(outerCb)).toEqual([]); + expect(n1).toBe(0); + expect(n2).toBe(1); + }); + // test("notification is not done after unregistration", async () => { // let n = 0; // const observer = () => n++;