Skip to content

Commit

Permalink
Keep getStoreKeyName.setStringify but use canonicalStringify by default.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Sep 27, 2023
1 parent 50e485a commit 911232e
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 66 deletions.
6 changes: 3 additions & 3 deletions .api-reports/api-report-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,9 @@ interface WriteContext extends ReadMergeModifyContext {

// Warnings were encountered during analysis:
//
// src/cache/inmemory/policies.ts:92:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:95:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)
Expand Down
6 changes: 3 additions & 3 deletions .api-reports/api-report-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -2179,9 +2179,9 @@ interface WriteContext extends ReadMergeModifyContext {

// Warnings were encountered during analysis:
//
// src/cache/inmemory/policies.ts:92:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:95:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts
// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
Expand Down
22 changes: 16 additions & 6 deletions .api-reports/api-report-utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -1077,7 +1077,11 @@ export function getOperationName(doc: DocumentNode): string | null;
export function getQueryDefinition(doc: DocumentNode): OperationDefinitionNode;

// @public (undocumented)
export function getStoreKeyName(fieldName: string, args?: Record<string, any> | null, directives?: Directives): string;
export const getStoreKeyName: ((fieldName: string, args?: Record<string, any> | null, directives?: Directives) => string) & {
setStringify(s: typeof storeKeyNameStringify): ((value: any) => string) & {
reset(): void;
};
};

// @public (undocumented)
export function getTypenameFromResult(result: Record<string, any>, selectionSet: SelectionSetNode, fragmentMap?: FragmentMap): string | undefined;
Expand Down Expand Up @@ -2287,6 +2291,11 @@ type StorageType = Record<string, any>;
// @public (undocumented)
export function storeKeyNameFromField(field: FieldNode, variables?: Object): string;

// @public (undocumented)
let storeKeyNameStringify: ((value: any) => string) & {
reset(): void;
};

// @public (undocumented)
export interface StoreObject {
// (undocumented)
Expand Down Expand Up @@ -2498,11 +2507,11 @@ interface WriteContext extends ReadMergeModifyContext {
// Warnings were encountered during analysis:
//
// src/cache/core/types/DataProxy.ts:141:5 - (ae-forgotten-export) The symbol "MissingFieldError" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:57:3 - (ae-forgotten-export) The symbol "TypePolicy" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:162:3 - (ae-forgotten-export) The symbol "FieldReadFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:163:3 - (ae-forgotten-export) The symbol "FieldMergeFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:60:3 - (ae-forgotten-export) The symbol "TypePolicy" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:165:3 - (ae-forgotten-export) The symbol "FieldReadFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:166:3 - (ae-forgotten-export) The symbol "FieldMergeFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/writeToStore.ts:65:7 - (ae-forgotten-export) The symbol "MergeTree" needs to be exported by the entry point index.d.ts
// src/core/ApolloClient.ts:47:3 - (ae-forgotten-export) The symbol "UriFunction" needs to be exported by the entry point index.d.ts
Expand All @@ -2517,6 +2526,7 @@ interface WriteContext extends ReadMergeModifyContext {
// src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:205:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/storeUtils.ts:208:12 - (ae-forgotten-export) The symbol "storeKeyNameStringify" needs to be exported by the entry point index.d.ts
// src/utilities/policies/pagination.ts:76:3 - (ae-forgotten-export) The symbol "TRelayEdge" needs to be exported by the entry point index.d.ts
// src/utilities/policies/pagination.ts:77:3 - (ae-forgotten-export) The symbol "TRelayPageInfo" needs to be exported by the entry point index.d.ts

Expand Down
6 changes: 3 additions & 3 deletions .api-reports/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -2858,9 +2858,9 @@ interface WriteContext extends ReadMergeModifyContext {

// Warnings were encountered during analysis:
//
// src/cache/inmemory/policies.ts:92:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:161:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:95:3 - (ae-forgotten-export) The symbol "FragmentMap" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeySpecifier" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/policies.ts:164:3 - (ae-forgotten-export) The symbol "KeyArgsFunction" needs to be exported by the entry point index.d.ts
// src/cache/inmemory/types.ts:126:3 - (ae-forgotten-export) The symbol "KeyFieldsFunction" needs to be exported by the entry point index.d.ts
// src/core/ObservableQuery.ts:112:5 - (ae-forgotten-export) The symbol "QueryManager" needs to be exported by the entry point index.d.ts
// src/core/ObservableQuery.ts:113:5 - (ae-forgotten-export) The symbol "QueryInfo" needs to be exported by the entry point index.d.ts
Expand Down
4 changes: 2 additions & 2 deletions .size-limit.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const checks = [
{
path: "dist/apollo-client.min.cjs",
limit: "38060",
limit: "38090",
},
{
path: "dist/main.cjs",
Expand All @@ -10,7 +10,7 @@ const checks = [
{
path: "dist/index.js",
import: "{ ApolloClient, InMemoryCache, HttpLink }",
limit: "32095",
limit: "32126",
},
...[
"ApolloProvider",
Expand Down
3 changes: 3 additions & 0 deletions src/cache/inmemory/policies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getStoreKeyName,
isNonNullObject,
stringifyForDisplay,
canonicalStringify,
} from "../../utilities/index.js";
import type {
IdGetter,
Expand Down Expand Up @@ -53,6 +54,8 @@ import {
keyFieldsFnFromSpecifier,
} from "./key-extractor.js";

getStoreKeyName.setStringify(canonicalStringify);

export type TypePolicies = {
[__typename: string]: TypePolicy;
};
Expand Down
114 changes: 65 additions & 49 deletions src/utilities/graphql/storeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,62 +195,78 @@ const KNOWN_DIRECTIVES: string[] = [
"nonreactive",
];

export function getStoreKeyName(
fieldName: string,
args?: Record<string, any> | null,
directives?: Directives
): string {
if (
args &&
directives &&
directives["connection"] &&
directives["connection"]["key"]
) {
// Default stable JSON.stringify implementation used by getStoreKeyName. Can be
// updated/replaced with something better by calling
// getStoreKeyName.setStringify(newStringifyFunction).
let storeKeyNameStringify = canonicalStringify;

export const getStoreKeyName = Object.assign(
function (
fieldName: string,
args?: Record<string, any> | null,
directives?: Directives
): string {
if (
directives["connection"]["filter"] &&
(directives["connection"]["filter"] as string[]).length > 0
args &&
directives &&
directives["connection"] &&
directives["connection"]["key"]
) {
const filterKeys = directives["connection"]["filter"]
? (directives["connection"]["filter"] as string[])
: [];
filterKeys.sort();

const filteredArgs = {} as { [key: string]: any };
filterKeys.forEach((key) => {
filteredArgs[key] = args[key];
});

return `${directives["connection"]["key"]}(${canonicalStringify(
filteredArgs
)})`;
} else {
return directives["connection"]["key"];
if (
directives["connection"]["filter"] &&
(directives["connection"]["filter"] as string[]).length > 0
) {
const filterKeys = directives["connection"]["filter"]
? (directives["connection"]["filter"] as string[])
: [];
filterKeys.sort();

const filteredArgs = {} as { [key: string]: any };
filterKeys.forEach((key) => {
filteredArgs[key] = args[key];
});

return `${directives["connection"]["key"]}(${storeKeyNameStringify(
filteredArgs
)})`;
} else {
return directives["connection"]["key"];
}
}
}

let completeFieldName: string = fieldName;
let completeFieldName: string = fieldName;

if (args) {
// We can't use `JSON.stringify` here since it's non-deterministic,
// and can lead to different store key names being created even though
// the `args` object used during creation has the same properties/values.
const stringifiedArgs: string = canonicalStringify(args);
completeFieldName += `(${stringifiedArgs})`;
}
if (args) {
// We can't use `JSON.stringify` here since it's non-deterministic,
// and can lead to different store key names being created even though
// the `args` object used during creation has the same properties/values.
const stringifiedArgs: string = storeKeyNameStringify(args);
completeFieldName += `(${stringifiedArgs})`;
}

if (directives) {
Object.keys(directives).forEach((key) => {
if (KNOWN_DIRECTIVES.indexOf(key) !== -1) return;
if (directives[key] && Object.keys(directives[key]).length) {
completeFieldName += `@${key}(${canonicalStringify(directives[key])})`;
} else {
completeFieldName += `@${key}`;
}
});
}
if (directives) {
Object.keys(directives).forEach((key) => {
if (KNOWN_DIRECTIVES.indexOf(key) !== -1) return;
if (directives[key] && Object.keys(directives[key]).length) {
completeFieldName += `@${key}(${storeKeyNameStringify(
directives[key]
)})`;
} else {
completeFieldName += `@${key}`;
}
});
}

return completeFieldName;
}
return completeFieldName;
},
{
setStringify(s: typeof storeKeyNameStringify) {
const previous = storeKeyNameStringify;
storeKeyNameStringify = s;
return previous;
},
}
);

export function argumentsObjectFromField(
field: FieldNode | DirectiveNode,
Expand Down

0 comments on commit 911232e

Please sign in to comment.