Skip to content

Commit

Permalink
fix(useStorage): ensure setting value to null syncs to other instances (
Browse files Browse the repository at this point in the history
#3737)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
callumacrae and antfu committed Feb 20, 2024
1 parent ad3ca86 commit f7ea105
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
15 changes: 15 additions & 0 deletions packages/core/useStorage/index.test.ts
Expand Up @@ -464,6 +464,21 @@ describe('useStorage', () => {
expect(call[0].detail.key).toEqual(KEY)
expect(call[0].detail.oldValue).toEqual('0')
expect(call[0].detail.newValue).toEqual('1')

window.addEventListener(customStorageEventName, eventFn, { once: true })

data0.value = null
await nextTwoTick()

expect(data0.value).toBe(0)
expect(data1.value).toBe(0)
expect(eventFn).toHaveBeenCalledTimes(2)
const call2 = eventFn.mock.calls[1] as [CustomEvent]

expect(call2[0].detail.storageArea).toEqual(storage)
expect(call2[0].detail.key).toEqual(KEY)
expect(call2[0].detail.oldValue).toEqual('1')
expect(call2[0].detail.newValue).toEqual(null)
})

it('handle error', () => {
Expand Down
35 changes: 20 additions & 15 deletions packages/core/useStorage/index.ts
Expand Up @@ -195,28 +195,33 @@ export function useStorage<T extends(string | number | boolean | object | null)>

function write(v: unknown) {
try {
const oldValue = storage!.getItem(key)

const dispatchWriteEvent = (newValue: string | null) => {
// send custom event to communicate within same page
// importantly this should _not_ be a StorageEvent since those cannot
// be constructed with a non-built-in storage area
if (window) {
window.dispatchEvent(new CustomEvent<StorageEventLike>(customStorageEventName, {
detail: {
key,
oldValue,
newValue,
storageArea: storage!,
},
}))
}
}

if (v == null) {
dispatchWriteEvent(null)
storage!.removeItem(key)
}
else {
const serialized = serializer.write(v as any)
const oldValue = storage!.getItem(key)
if (oldValue !== serialized) {
storage!.setItem(key, serialized)

// send custom event to communicate within same page
// importantly this should _not_ be a StorageEvent since those cannot
// be constructed with a non-built-in storage area
if (window) {
window.dispatchEvent(new CustomEvent<StorageEventLike>(customStorageEventName, {
detail: {
key,
oldValue,
newValue: serialized,
storageArea: storage!,
},
}))
}
dispatchWriteEvent(serialized)
}
}
}
Expand Down

0 comments on commit f7ea105

Please sign in to comment.