diff --git a/src/utils.ts b/src/utils.ts index 5a4c011a1..ffe1a021f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -76,6 +76,13 @@ export function prefixStorage( return storage.setItems(prefixedItems, commonOptions); }; + nsStorage.watch = (callback) => + storage.watch((event, key) => { + if (key.startsWith(base)) { + callback(event, key.slice(base.length)); + } + }); + return nsStorage; } diff --git a/test/storage.test.ts b/test/storage.test.ts index 2cef5f54d..0f9ffc628 100644 --- a/test/storage.test.ts +++ b/test/storage.test.ts @@ -274,4 +274,26 @@ describe("Regression", () => { { key: "key2", value: "value2" }, ]); }); + + it("prefixStorage watch strips prefix and filters events", async () => { + const storage = createStorage(); + const pStorage = prefixStorage(storage, "ns"); + + const events: { event: string; key: string }[] = []; + const unwatch = await pStorage.watch((event, key) => { + events.push({ event, key }); + }); + + await pStorage.setItem("foo", "bar"); + await storage.setItem("other:x", "y"); + + // give the synchronous memory-driver onChange time to flush + await new Promise((resolve) => setTimeout(resolve, 10)); + await unwatch(); + + // key delivered to the callback should be relative (no "ns:" prefix) + expect(events).toContainEqual({ event: "update", key: "foo" }); + // events for keys outside the prefix must be filtered out + expect(events.every((e) => !e.key.startsWith("other"))).toBe(true); + }); });