diff --git a/.changeset/serious-lobsters-smell.md b/.changeset/serious-lobsters-smell.md new file mode 100644 index 000000000..055421141 --- /dev/null +++ b/.changeset/serious-lobsters-smell.md @@ -0,0 +1,5 @@ +--- +'houdini': patch +--- + +Fix issue when writing oevr previously null value diff --git a/packages/houdini/src/runtime/cache/cache.ts b/packages/houdini/src/runtime/cache/cache.ts index 164cdcb2e..e7ab09fea 100644 --- a/packages/houdini/src/runtime/cache/cache.ts +++ b/packages/houdini/src/runtime/cache/cache.ts @@ -594,7 +594,9 @@ class CacheInternal { else if ( Array.isArray(value) && // make typescript happy - (typeof previousValue === 'undefined' || Array.isArray(previousValue)) + (typeof previousValue === 'undefined' || + previousValue === null || + Array.isArray(previousValue)) ) { // make a shallow copy of the previous value we can mutate let oldIDs = [...(previousValue || [])] as (string | null)[] @@ -732,7 +734,7 @@ class CacheInternal { // or we got content for a new list which could already be known. If we just look at // whether the IDs are the same, situations where we have old data that // is still valid would not be triggered - const contentChanged = !deepEquals(linkedIDs, oldIDs) + const contentChanged = !deepEquals(linkedIDs, oldIDs) || previousValue === null // we need to look at the last time we saw each subscriber to check if they need to be added to the spec if (contentChanged || forceNotify) { diff --git a/packages/houdini/src/runtime/cache/tests/subscriptions.test.ts b/packages/houdini/src/runtime/cache/tests/subscriptions.test.ts index c3681bd83..aa620b174 100644 --- a/packages/houdini/src/runtime/cache/tests/subscriptions.test.ts +++ b/packages/houdini/src/runtime/cache/tests/subscriptions.test.ts @@ -2880,3 +2880,62 @@ test('reverting optimistic remove notifies subscribers', function () { test.todo('can write to and resolve layers') test.todo("resolving a layer with the same value as the most recent doesn't notify subscribers") + +test('overwrite null value with list', function () { + // instantiate the cache + const cache = new Cache(config) + + const selection: SubscriptionSelection = { + fields: { + friends: { + type: 'User', + visible: true, + keyRaw: 'friends', + selection: { + fields: { + id: { + type: 'ID', + visible: true, + keyRaw: 'id', + }, + firstName: { + type: 'String', + visible: true, + keyRaw: 'firstName', + }, + }, + }, + }, + }, + } + + // add some data to the cache + cache.write({ + selection, + data: { + friends: null, + }, + }) + + // a function to spy on that will play the role of set + const set = vi.fn() + + // subscribe to the fields + cache.subscribe({ + rootType: 'Query', + selection: selection, + set: set, + }) + + // add some data to the cache + cache.write({ + selection, + data: { + friends: [], + }, + }) + + expect(set).toHaveBeenCalledWith({ + friends: [], + }) +})