Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

(fix) - Fix data persistence for embedded fields (#727)

authored by

Phil Plückthun and committed by
GitHub
4b926d73 6bd5238f

+69 -2
+5
.changeset/nine-grapes-lay.md
··· 1 + --- 2 + '@urql/exchange-graphcache': patch 3 + --- 4 + 5 + Fix data persistence for embedded fields
+8
exchanges/graphcache/src/store/__snapshots__/store.test.ts.snap
··· 1 1 // Jest Snapshot v1, https://goo.gl/fbAQLP 2 2 3 + exports[`Store with storage should be able to persist embedded data 1`] = ` 4 + Object { 5 + "Query%2eappointment({\\"id\\":\\"1\\"}).__typename": "\\"Appointment\\"", 6 + "Query%2eappointment({\\"id\\":\\"1\\"}).info": "\\"urql meeting\\"", 7 + "Query.appointment({\\"id\\":\\"1\\"})": ":\\"Query.appointment({\\\\\\"id\\\\\\":\\\\\\"1\\\\\\"})\\"", 8 + } 9 + `; 10 + 3 11 exports[`Store with storage should be able to store and rehydrate data 1`] = ` 4 12 Object { 5 13 "Appointment:1.__typename": "\\"Appointment\\"",
+2 -2
exchanges/graphcache/src/store/keys.ts
··· 25 25 }; 26 26 27 27 export const serializeKeys = (entityKey: string, fieldKey: string) => 28 - `${entityKey.replace(/\./g, '\\.')}.${fieldKey}`; 28 + `${entityKey.replace(/\./g, '%2e')}.${fieldKey}`; 29 29 30 30 export const deserializeKeyInfo = (key: string): KeyInfo => { 31 31 const dotIndex = key.indexOf('.'); 32 - const entityKey = key.slice(0, dotIndex).replace(/\\\./g, '.'); 32 + const entityKey = key.slice(0, dotIndex).replace(/%2e/g, '.'); 33 33 const fieldKey = key.slice(dotIndex + 1); 34 34 return { entityKey, fieldKey }; 35 35 };
+54
exchanges/graphcache/src/store/store.test.ts
··· 541 541 expect(data).toEqual(expectedData); 542 542 }); 543 543 544 + it('should be able to persist embedded data', () => { 545 + const EmbeddedAppointment = gql` 546 + query appointment($id: String) { 547 + appointment(id: $id) { 548 + __typename 549 + info 550 + } 551 + } 552 + `; 553 + 554 + const embeddedData = { 555 + ...expectedData, 556 + appointment: { 557 + ...expectedData.appointment, 558 + id: undefined, 559 + }, 560 + } as any; 561 + 562 + const storage: StorageAdapter = { 563 + read: jest.fn(), 564 + write: jest.fn(), 565 + }; 566 + 567 + store.data.storage = storage; 568 + 569 + write( 570 + store, 571 + { 572 + query: EmbeddedAppointment, 573 + variables: { id: '1' }, 574 + }, 575 + embeddedData 576 + ); 577 + 578 + InMemoryData.initDataState(store.data, null); 579 + InMemoryData.persistData(); 580 + InMemoryData.clearDataState(); 581 + 582 + expect(storage.write).toHaveBeenCalled(); 583 + 584 + const serialisedStore = (storage.write as any).mock.calls[0][0]; 585 + expect(serialisedStore).toMatchSnapshot(); 586 + 587 + store = new Store(); 588 + InMemoryData.hydrateData(store.data, storage, serialisedStore); 589 + 590 + const { data } = query(store, { 591 + query: EmbeddedAppointment, 592 + variables: { id: '1' }, 593 + }); 594 + 595 + expect(data).toEqual(embeddedData); 596 + }); 597 + 544 598 it('persists commutative layers and ignores optimistic layers', () => { 545 599 const storage: StorageAdapter = { 546 600 read: jest.fn(),