Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to provide underlying storage for ssr exchange #3728

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fluffy-mirrors-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/core': minor
---

allow to provide underlying storage for ssr exchange
27 changes: 26 additions & 1 deletion packages/core/src/exchanges/ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Client } from '../client';
import { queryOperation, queryResponse } from '../test-utils';
import { ExchangeIO, Operation, OperationResult } from '../types';
import { CombinedError, formatDocument } from '../utils';
import { ssrExchange } from './ssr';
import { SSRDataStorage, ssrExchange } from './ssr';

let forward: ExchangeIO;
let exchangeInput;
Expand Down Expand Up @@ -52,6 +52,31 @@ it('caches query results correctly', () => {
});
});

it('caches query results correctly when storage is provided', () => {
output.mockReturnValueOnce(queryResponse);

const storage: SSRDataStorage = {};
const ssr = ssrExchange({ storage });
const { source: ops$, next } = input;
const exchange = ssr(exchangeInput)(ops$);

publish(exchange);
next(queryOperation);

const data = ssr.extractData();
expect(storage).toEqual(data);

expect(Object.keys(storage)).toEqual(['' + queryOperation.key]);

expect(storage).toEqual({
[queryOperation.key]: {
data: serializedQueryResponse.data,
error: undefined,
hasNext: false,
},
});
});

it('serializes query results quickly', () => {
const result: OperationResult = {
...queryResponse,
Expand Down
12 changes: 11 additions & 1 deletion packages/core/src/exchanges/ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export interface SSRData {
[key: string]: SerializedResult;
}

export interface SSRDataStorage {
[key: string]: SerializedResult | null;
}

/** Options for the `ssrExchange` allowing it to either operate on the server- or client-side. */
export interface SSRExchangeParams {
/** Indicates to the {@link SSRExchange} whether it's currently in server-side or client-side mode.
Expand Down Expand Up @@ -74,6 +78,11 @@ export interface SSRExchangeParams {
* not serialize this data by default, unless this flag is set.
*/
includeExtensions?: boolean;

/**
* If provided, this will be used as underlying storage for the serialized results.
*/
storage?: SSRDataStorage;
}

/** An `SSRExchange` either in server-side mode, serializing results, or client-side mode, deserializing and replaying results..
Expand Down Expand Up @@ -188,7 +197,8 @@ const revalidated = new Set<number>();
export const ssrExchange = (params: SSRExchangeParams = {}): SSRExchange => {
const staleWhileRevalidate = !!params.staleWhileRevalidate;
const includeExtensions = !!params.includeExtensions;
const data: Record<string, SerializedResult | null> = {};
const data: SSRDataStorage =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we do this with initialState? For instance when we run extractData we extract into this custom storage and on the client we can leverage the restoreData method and initialState to restore additional and the initial entries.

This is similar to our nextjs solution

params.storage !== undefined ? params.storage : {};

// On the client-side, we delete results from the cache as they're resolved
// this is delayed so that concurrent queries don't delete each other's data
Expand Down
Loading