@apollo/client 3.5.5 → 3.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apollo-client.cjs +141 -144
- package/apollo-client.cjs.map +1 -1
- package/apollo-client.min.cjs +1 -1
- package/cache/cache.cjs +21 -20
- package/cache/cache.cjs.map +1 -1
- package/cache/inmemory/helpers.d.ts +1 -0
- package/cache/inmemory/helpers.d.ts.map +1 -1
- package/cache/inmemory/helpers.js +3 -2
- package/cache/inmemory/helpers.js.map +1 -1
- package/cache/inmemory/key-extractor.js +5 -5
- package/cache/inmemory/key-extractor.js.map +1 -1
- package/cache/inmemory/object-canon.d.ts.map +1 -1
- package/cache/inmemory/object-canon.js +2 -1
- package/cache/inmemory/object-canon.js.map +1 -1
- package/cache/inmemory/policies.d.ts +1 -1
- package/cache/inmemory/policies.d.ts.map +1 -1
- package/cache/inmemory/policies.js +6 -6
- package/cache/inmemory/policies.js.map +1 -1
- package/cache/inmemory/readFromStore.js +3 -3
- package/cache/inmemory/readFromStore.js.map +1 -1
- package/cache/inmemory/writeToStore.js +7 -7
- package/cache/inmemory/writeToStore.js.map +1 -1
- package/core/ObservableQuery.d.ts.map +1 -1
- package/core/ObservableQuery.js +6 -3
- package/core/ObservableQuery.js.map +1 -1
- package/core/core.cjs +7 -4
- package/core/core.cjs.map +1 -1
- package/invariantErrorCodes.js +3 -3
- package/package.json +14 -14
- package/react/hooks/hooks.cjs +113 -120
- package/react/hooks/hooks.cjs.map +1 -1
- package/react/hooks/useApolloClient.js +2 -2
- package/react/hooks/useApolloClient.js.map +1 -1
- package/react/hooks/useLazyQuery.d.ts.map +1 -1
- package/react/hooks/useLazyQuery.js +20 -27
- package/react/hooks/useLazyQuery.js.map +1 -1
- package/react/hooks/useMutation.d.ts.map +1 -1
- package/react/hooks/useMutation.js +59 -68
- package/react/hooks/useMutation.js.map +1 -1
- package/react/hooks/useQuery.d.ts.map +1 -1
- package/react/hooks/useQuery.js +25 -17
- package/react/hooks/useQuery.js.map +1 -1
- package/react/hooks/useSubscription.d.ts.map +1 -1
- package/react/hooks/useSubscription.js +10 -8
- package/react/hooks/useSubscription.js.map +1 -1
- package/react/types/types.d.ts +1 -1
- package/react/types/types.d.ts.map +1 -1
- package/react/types/types.js.map +1 -1
- package/utilities/globals/global.d.ts +2 -8
- package/utilities/globals/global.d.ts.map +1 -1
- package/utilities/globals/global.js +1 -1
- package/utilities/globals/global.js.map +1 -1
- package/utilities/globals/globals.cjs +1 -1
- package/utilities/globals/globals.cjs.map +1 -1
- package/version.js +1 -1
|
@@ -17,4 +17,5 @@ export declare function fieldNameFromStoreName(storeFieldName: string): string;
|
|
|
17
17
|
export declare function selectionSetMatchesResult(selectionSet: SelectionSetNode, result: Record<string, any>, variables?: Record<string, any>): boolean;
|
|
18
18
|
export declare function storeValueIsStoreObject(value: StoreValue): value is StoreObject;
|
|
19
19
|
export declare function makeProcessedFieldsMerger(): DeepMerger<any[]>;
|
|
20
|
+
export declare const isArray: (a: any) => a is any[] | readonly any[];
|
|
20
21
|
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,SAAS,EAET,UAAU,EACV,WAAW,EAEX,UAAU,EAKX,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MACW,MAAM,6BACJ,CAAC;AAErB,wBAAgB,uBAAuB,CACrC,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC9C,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,GAAG,SAAS,CAiBpB;AAWD,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB;;;;;wBAE1D;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,GACnD,OAAO,CAGT;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EACtB,iBAAiB,EAAE,WAAW,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAIpB;AAED,eAAO,MAAM,qBAAqB,QAAuB,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CAoBT;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,GAChB,KAAK,IAAI,WAAW,CAItB;AAED,wBAAgB,yBAAyB,sBAExC"}
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,SAAS,EAET,UAAU,EACV,WAAW,EAEX,UAAU,EAKX,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MACW,MAAM,6BACJ,CAAC;AAErB,wBAAgB,uBAAuB,CACrC,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC9C,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,GAAG,SAAS,CAiBpB;AAWD,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB;;;;;wBAE1D;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,GACnD,OAAO,CAGT;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EACtB,iBAAiB,EAAE,WAAW,GAAG,SAAS,GACzC,MAAM,GAAG,SAAS,CAIpB;AAED,eAAO,MAAM,qBAAqB,QAAuB,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CAoBT;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,GAChB,KAAK,IAAI,WAAW,CAItB;AAED,wBAAgB,yBAAyB,sBAExC;AAED,eAAO,MAAM,OAAO,MAAO,GAAG,gCAAkD,CAAA"}
|
|
@@ -42,7 +42,7 @@ export function fieldNameFromStoreName(storeFieldName) {
|
|
|
42
42
|
}
|
|
43
43
|
export function selectionSetMatchesResult(selectionSet, result, variables) {
|
|
44
44
|
if (isNonNullObject(result)) {
|
|
45
|
-
return
|
|
45
|
+
return isArray(result)
|
|
46
46
|
? result.every(function (item) { return selectionSetMatchesResult(selectionSet, item, variables); })
|
|
47
47
|
: selectionSet.selections.every(function (field) {
|
|
48
48
|
if (isField(field) && shouldInclude(field, variables)) {
|
|
@@ -59,9 +59,10 @@ export function selectionSetMatchesResult(selectionSet, result, variables) {
|
|
|
59
59
|
export function storeValueIsStoreObject(value) {
|
|
60
60
|
return isNonNullObject(value) &&
|
|
61
61
|
!isReference(value) &&
|
|
62
|
-
!
|
|
62
|
+
!isArray(value);
|
|
63
63
|
}
|
|
64
64
|
export function makeProcessedFieldsMerger() {
|
|
65
65
|
return new DeepMerger;
|
|
66
66
|
}
|
|
67
|
+
export var isArray = function (a) { return Array.isArray(a); };
|
|
67
68
|
//# sourceMappingURL=helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/cache/inmemory/helpers.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,WAAW,EAGX,OAAO,EACP,UAAU,EACV,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,OAAO,GACR,MAAM,iBAAiB,CAAC;AAEzB,MAAM,CACJ,IAAgB,MAAM,GACpB,MAAM,CAAC,SAAS,eADI,CACH;AAErB,MAAM,UAAU,uBAAuB,CACrC,EAA8C,EAC9C,OAA0B;QADxB,UAAU,gBAAA,EAAE,EAAE,QAAA,EAAE,GAAG,SAAA;IAGrB,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;QAClC,IAAI,OAAO,EAAE;YACX,OAAO,CAAC,SAAS;gBACd,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAG,EAAE,IAAA,EAAE,CAAC,CAAC;oBAC1B,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAA,EAAE,CAAC,CAAC;wBAC1B,KAAK,CAAC,CAAC;SACV;QAED,IAAI,EAAE,KAAK,KAAK,CAAC;YAAE,EAAE,GAAG,GAAG,CAAC;QAC5B,IAAI,EAAE,KAAK,KAAK,CAAC,EAAE;YACjB,OAAO,UAAG,UAAU,cAAI,CACtB,OAAO,EAAE,KAAK,QAAQ;gBACtB,OAAO,EAAE,KAAK,QAAQ,CACvB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAE,CAAC;SAC/B;KACF;AACH,CAAC;AAED,IAAM,aAAa,GAAG;IACpB,gBAAgB,EAAE,uBAAuB;IACzC,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IAGnB,eAAe,EAAE,KAAK;CACvB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAA2B;IACzD,OAAO,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAAoD;IAEpD,IAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC;IACrC,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAAsB,EACtB,iBAA0C;IAE1C,OAAO,WAAW,CAAC,iBAAiB,CAAC;QACnC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAW;QAC5D,CAAC,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,UAAU,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,IAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAE1D,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,IAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,YAA8B,EAC9B,MAA2B,EAC3B,SAA+B;IAE/B,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE;QAC3B,OAAO,
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/cache/inmemory/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { SelectionSetNode } from 'graphql';\n\nimport {\n NormalizedCache,\n InMemoryCacheConfig,\n} from './types';\n\nimport { KeyFieldsContext } from './policies';\n\nimport {\n Reference,\n isReference,\n StoreValue,\n StoreObject,\n isField,\n DeepMerger,\n resultKeyNameFromField,\n shouldInclude,\n isNonNullObject,\n compact,\n} from '../../utilities';\n\nexport const {\n hasOwnProperty: hasOwn,\n} = Object.prototype;\n\nexport function defaultDataIdFromObject(\n { __typename, id, _id }: Readonly<StoreObject>,\n context?: KeyFieldsContext,\n): string | undefined {\n if (typeof __typename === \"string\") {\n if (context) {\n context.keyObject =\n id !== void 0 ? { id } :\n _id !== void 0 ? { _id } :\n void 0;\n }\n // If there is no object.id, fall back to object._id.\n if (id === void 0) id = _id;\n if (id !== void 0) {\n return `${__typename}:${(\n typeof id === \"number\" ||\n typeof id === \"string\"\n ) ? id : JSON.stringify(id)}`;\n }\n }\n}\n\nconst defaultConfig = {\n dataIdFromObject: defaultDataIdFromObject,\n addTypename: true,\n resultCaching: true,\n // Thanks to the shouldCanonizeResults helper, this should be the only line\n // you have to change to reenable canonization by default in the future.\n canonizeResults: false,\n};\n\nexport function normalizeConfig(config: InMemoryCacheConfig) {\n return compact(defaultConfig, config);\n}\n\nexport function shouldCanonizeResults(\n config: Pick<InMemoryCacheConfig, \"canonizeResults\">,\n): boolean {\n const value = config.canonizeResults;\n return value === void 0 ? defaultConfig.canonizeResults : value;\n}\n\nexport function getTypenameFromStoreObject(\n store: NormalizedCache,\n objectOrReference: StoreObject | Reference,\n): string | undefined {\n return isReference(objectOrReference)\n ? store.get(objectOrReference.__ref, \"__typename\") as string\n : objectOrReference && objectOrReference.__typename;\n}\n\nexport const TypeOrFieldNameRegExp = /^[_a-z][_0-9a-z]*/i;\n\nexport function fieldNameFromStoreName(storeFieldName: string): string {\n const match = storeFieldName.match(TypeOrFieldNameRegExp);\n return match ? match[0] : storeFieldName;\n}\n\nexport function selectionSetMatchesResult(\n selectionSet: SelectionSetNode,\n result: Record<string, any>,\n variables?: Record<string, any>,\n): boolean {\n if (isNonNullObject(result)) {\n return isArray(result)\n ? result.every(item => selectionSetMatchesResult(selectionSet, item, variables))\n : selectionSet.selections.every(field => {\n if (isField(field) && shouldInclude(field, variables)) {\n const key = resultKeyNameFromField(field);\n return hasOwn.call(result, key) &&\n (!field.selectionSet ||\n selectionSetMatchesResult(field.selectionSet, result[key], variables));\n }\n // If the selection has been skipped with @skip(true) or\n // @include(false), it should not count against the matching. If\n // the selection is not a field, it must be a fragment (inline or\n // named). We will determine if selectionSetMatchesResult for that\n // fragment when we get to it, so for now we return true.\n return true;\n });\n }\n return false;\n}\n\nexport function storeValueIsStoreObject(\n value: StoreValue,\n): value is StoreObject {\n return isNonNullObject(value) &&\n !isReference(value) &&\n !isArray(value);\n}\n\nexport function makeProcessedFieldsMerger() {\n return new DeepMerger;\n}\n\nexport const isArray = (a: any): a is any[] | readonly any[] => Array.isArray(a)\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { invariant } from "../../utilities/globals/index.js";
|
|
2
2
|
import { argumentsObjectFromField, DeepMerger, isNonEmptyArray, isNonNullObject, } from "../../utilities/index.js";
|
|
3
|
-
import { hasOwn } from "./helpers.js";
|
|
3
|
+
import { hasOwn, isArray } from "./helpers.js";
|
|
4
4
|
var specifierInfoCache = Object.create(null);
|
|
5
5
|
function lookupSpecifierInfo(spec) {
|
|
6
6
|
var cacheKey = JSON.stringify(spec);
|
|
@@ -80,13 +80,13 @@ export function getSpecifierPaths(spec) {
|
|
|
80
80
|
var paths_1 = info.paths = [];
|
|
81
81
|
var currentPath_1 = [];
|
|
82
82
|
spec.forEach(function (s, i) {
|
|
83
|
-
if (
|
|
83
|
+
if (isArray(s)) {
|
|
84
84
|
getSpecifierPaths(s).forEach(function (p) { return paths_1.push(currentPath_1.concat(p)); });
|
|
85
85
|
currentPath_1.length = 0;
|
|
86
86
|
}
|
|
87
87
|
else {
|
|
88
88
|
currentPath_1.push(s);
|
|
89
|
-
if (!
|
|
89
|
+
if (!isArray(spec[i + 1])) {
|
|
90
90
|
paths_1.push(currentPath_1.slice(0));
|
|
91
91
|
currentPath_1.length = 0;
|
|
92
92
|
}
|
|
@@ -101,14 +101,14 @@ function extractKey(object, key) {
|
|
|
101
101
|
export function extractKeyPath(object, path, extract) {
|
|
102
102
|
extract = extract || extractKey;
|
|
103
103
|
return normalize(path.reduce(function reducer(obj, key) {
|
|
104
|
-
return
|
|
104
|
+
return isArray(obj)
|
|
105
105
|
? obj.map(function (child) { return reducer(child, key); })
|
|
106
106
|
: obj && extract(obj, key);
|
|
107
107
|
}, object));
|
|
108
108
|
}
|
|
109
109
|
function normalize(value) {
|
|
110
110
|
if (isNonNullObject(value)) {
|
|
111
|
-
if (
|
|
111
|
+
if (isArray(value)) {
|
|
112
112
|
return value.map(normalize);
|
|
113
113
|
}
|
|
114
114
|
return collectSpecifierPaths(Object.keys(value).sort(), function (path) { return extractKeyPath(value, path); });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-extractor.js","sourceRoot":"","sources":["../../../src/cache/inmemory/key-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../../utilities/globals\";\n\nimport {\n argumentsObjectFromField,\n DeepMerger,\n isNonEmptyArray,\n isNonNullObject,\n} from \"../../utilities\";\n\nimport { hasOwn } from \"./helpers\";\nimport {\n KeySpecifier,\n KeyFieldsFunction,\n KeyArgsFunction,\n} from \"./policies\";\n\n// Mapping from JSON-encoded KeySpecifier strings to associated information.\nconst specifierInfoCache: Record<string, {\n paths?: string[][];\n keyFieldsFn?: KeyFieldsFunction;\n keyArgsFn?: KeyArgsFunction;\n}> = Object.create(null);\n\nfunction lookupSpecifierInfo(spec: KeySpecifier) {\n // It's safe to encode KeySpecifier arrays with JSON.stringify, since they're\n // just arrays of strings or nested KeySpecifier arrays, and the order of the\n // array elements is important (and suitably preserved by JSON.stringify).\n const cacheKey = JSON.stringify(spec);\n return specifierInfoCache[cacheKey] ||\n (specifierInfoCache[cacheKey] = Object.create(null));\n}\n\nexport function keyFieldsFnFromSpecifier(\n specifier: KeySpecifier,\n): KeyFieldsFunction {\n const info = lookupSpecifierInfo(specifier);\n\n return info.keyFieldsFn || (info.keyFieldsFn = (\n object,\n context,\n ) => {\n const extract: typeof extractKey =\n (from, key) => context.readField(key, from);\n\n const keyObject = context.keyObject = collectSpecifierPaths(\n specifier,\n schemaKeyPath => {\n let extracted = extractKeyPath(\n context.storeObject,\n schemaKeyPath,\n // Using context.readField to extract paths from context.storeObject\n // allows the extraction to see through Reference objects and respect\n // custom read functions.\n extract,\n );\n\n if (\n extracted === void 0 &&\n object !== context.storeObject &&\n hasOwn.call(object, schemaKeyPath[0])\n ) {\n // If context.storeObject fails to provide a value for the requested\n // path, fall back to the raw result object, if it has a top-level key\n // matching the first key in the path (schemaKeyPath[0]). This allows\n // key fields included in the written data to be saved in the cache\n // even if they are not selected explicitly in context.selectionSet.\n // Not being mentioned by context.selectionSet is convenient here,\n // since it means these extra fields cannot be affected by field\n // aliasing, which is why we can use extractKey instead of\n // context.readField for this extraction.\n extracted = extractKeyPath(object, schemaKeyPath, extractKey);\n }\n\n invariant(\n extracted !== void 0,\n `Missing field '${schemaKeyPath.join('.')}' while extracting keyFields from ${\n JSON.stringify(object)\n }`,\n );\n\n return extracted;\n },\n );\n\n return `${context.typename}:${JSON.stringify(keyObject)}`;\n });\n}\n\n// The keyArgs extraction process is roughly analogous to keyFields extraction,\n// but there are no aliases involved, missing fields are tolerated (by merely\n// omitting them from the key), and drawing from field.directives or variables\n// is allowed (in addition to drawing from the field's arguments object).\n// Concretely, these differences mean passing a different key path extractor\n// function to collectSpecifierPaths, reusing the shared extractKeyPath helper\n// wherever possible.\nexport function keyArgsFnFromSpecifier(specifier: KeySpecifier): KeyArgsFunction {\n const info = lookupSpecifierInfo(specifier);\n\n return info.keyArgsFn || (info.keyArgsFn = (args, {\n field,\n variables,\n fieldName,\n }) => {\n const collected = collectSpecifierPaths(specifier, keyPath => {\n const firstKey = keyPath[0];\n const firstChar = firstKey.charAt(0);\n\n if (firstChar === \"@\") {\n if (field && isNonEmptyArray(field.directives)) {\n const directiveName = firstKey.slice(1);\n // If the directive appears multiple times, only the first\n // occurrence's arguments will be used. TODO Allow repetition?\n // TODO Cache this work somehow, a la aliasMap?\n const d = field.directives.find(d => d.name.value === directiveName);\n // Fortunately argumentsObjectFromField works for DirectiveNode!\n const directiveArgs = d && argumentsObjectFromField(d, variables);\n // For directives without arguments (d defined, but directiveArgs ===\n // null), the presence or absence of the directive still counts as\n // part of the field key, so we return null in those cases. If no\n // directive with this name was found for this field (d undefined and\n // thus directiveArgs undefined), we return undefined, which causes\n // this value to be omitted from the key object returned by\n // collectSpecifierPaths.\n return directiveArgs && extractKeyPath(\n directiveArgs,\n // If keyPath.length === 1, this code calls extractKeyPath with an\n // empty path, which works because it uses directiveArgs as the\n // extracted value.\n keyPath.slice(1),\n );\n }\n // If the key started with @ but there was no corresponding directive,\n // we want to omit this value from the key object, not fall through to\n // treating @whatever as a normal argument name.\n return;\n }\n\n if (firstChar === \"$\") {\n const variableName = firstKey.slice(1);\n if (variables && hasOwn.call(variables, variableName)) {\n const varKeyPath = keyPath.slice(0);\n varKeyPath[0] = variableName;\n return extractKeyPath(variables, varKeyPath);\n }\n // If the key started with $ but there was no corresponding variable, we\n // want to omit this value from the key object, not fall through to\n // treating $whatever as a normal argument name.\n return;\n }\n\n if (args) {\n return extractKeyPath(args, keyPath);\n }\n });\n\n const suffix = JSON.stringify(collected);\n\n // If no arguments were passed to this field, and it didn't have any other\n // field key contributions from directives or variables, hide the empty\n // :{} suffix from the field key. However, a field passed no arguments can\n // still end up with a non-empty :{...} suffix if its key configuration\n // refers to directives or variables.\n if (args || suffix !== \"{}\") {\n fieldName += \":\" + suffix;\n }\n\n return fieldName;\n });\n}\n\nexport function collectSpecifierPaths(\n specifier: KeySpecifier,\n extractor: (path: string[]) => any,\n): Record<string, any> {\n // For each path specified by specifier, invoke the extractor, and repeatedly\n // merge the results together, with appropriate ancestor context.\n const merger = new DeepMerger;\n return getSpecifierPaths(specifier).reduce((collected, path) => {\n let toMerge = extractor(path);\n if (toMerge !== void 0) {\n // This path is not expected to contain array indexes, so the toMerge\n // reconstruction will not contain arrays. TODO Fix this?\n for (let i = path.length - 1; i >= 0; --i) {\n toMerge = { [path[i]]: toMerge };\n }\n collected = merger.merge(collected, toMerge);\n }\n return collected;\n }, Object.create(null));\n}\n\nexport function getSpecifierPaths(spec: KeySpecifier): string[][] {\n const info = lookupSpecifierInfo(spec);\n\n if (!info.paths) {\n const paths: string[][] = info.paths = [];\n const currentPath: string[] = [];\n\n spec.forEach((s, i) => {\n if (Array.isArray(s)) {\n getSpecifierPaths(s).forEach(p => paths.push(currentPath.concat(p)));\n currentPath.length = 0;\n } else {\n currentPath.push(s);\n if (!Array.isArray(spec[i + 1])) {\n paths.push(currentPath.slice(0));\n currentPath.length = 0;\n }\n }\n });\n }\n\n return info.paths!;\n}\n\nfunction extractKey<\n TObj extends Record<string, any>,\n TKey extends string,\n>(object: TObj, key: TKey): TObj[TKey] | undefined {\n return object[key];\n}\n\nexport function extractKeyPath(\n object: Record<string, any>,\n path: string[],\n extract?: typeof extractKey,\n): any {\n // For each key in path, extract the corresponding child property from obj,\n // flattening arrays if encountered (uncommon for keyFields and keyArgs, but\n // possible). The final result of path.reduce is normalized so unexpected leaf\n // objects have their keys safely sorted. That final result is difficult to\n // type as anything other than any. You're welcome to try to improve the\n // return type, but keep in mind extractKeyPath is not a public function\n // (exported only for testing), so the effort may not be worthwhile unless the\n // limited set of actual callers (see above) pass arguments that TypeScript\n // can statically type. If we know only that path is some array of strings\n // (and not, say, a specific tuple of statically known strings), any (or\n // possibly unknown) is the honest answer.\n extract = extract || extractKey;\n return normalize(path.reduce(function reducer(obj, key): any {\n return Array.isArray(obj)\n ? obj.map(child => reducer(child, key))\n : obj && extract!(obj, key);\n }, object));\n}\n\nfunction normalize<T>(value: T): T {\n // Usually the extracted value will be a scalar value, since most primary\n // key fields are scalar, but just in case we get an object or an array, we\n // need to do some normalization of the order of (nested) keys.\n if (isNonNullObject(value)) {\n if (Array.isArray(value)) {\n return value.map(normalize) as any;\n }\n return collectSpecifierPaths(\n Object.keys(value).sort(),\n path => extractKeyPath(value, path),\n ) as T;\n }\n return value;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"key-extractor.js","sourceRoot":"","sources":["../../../src/cache/inmemory/key-extractor.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../../utilities/globals\";\n\nimport {\n argumentsObjectFromField,\n DeepMerger,\n isNonEmptyArray,\n isNonNullObject,\n} from \"../../utilities\";\n\nimport { hasOwn, isArray } from \"./helpers\";\nimport {\n KeySpecifier,\n KeyFieldsFunction,\n KeyArgsFunction,\n} from \"./policies\";\n\n// Mapping from JSON-encoded KeySpecifier strings to associated information.\nconst specifierInfoCache: Record<string, {\n paths?: string[][];\n keyFieldsFn?: KeyFieldsFunction;\n keyArgsFn?: KeyArgsFunction;\n}> = Object.create(null);\n\nfunction lookupSpecifierInfo(spec: KeySpecifier) {\n // It's safe to encode KeySpecifier arrays with JSON.stringify, since they're\n // just arrays of strings or nested KeySpecifier arrays, and the order of the\n // array elements is important (and suitably preserved by JSON.stringify).\n const cacheKey = JSON.stringify(spec);\n return specifierInfoCache[cacheKey] ||\n (specifierInfoCache[cacheKey] = Object.create(null));\n}\n\nexport function keyFieldsFnFromSpecifier(\n specifier: KeySpecifier,\n): KeyFieldsFunction {\n const info = lookupSpecifierInfo(specifier);\n\n return info.keyFieldsFn || (info.keyFieldsFn = (\n object,\n context,\n ) => {\n const extract: typeof extractKey =\n (from, key) => context.readField(key, from);\n\n const keyObject = context.keyObject = collectSpecifierPaths(\n specifier,\n schemaKeyPath => {\n let extracted = extractKeyPath(\n context.storeObject,\n schemaKeyPath,\n // Using context.readField to extract paths from context.storeObject\n // allows the extraction to see through Reference objects and respect\n // custom read functions.\n extract,\n );\n\n if (\n extracted === void 0 &&\n object !== context.storeObject &&\n hasOwn.call(object, schemaKeyPath[0])\n ) {\n // If context.storeObject fails to provide a value for the requested\n // path, fall back to the raw result object, if it has a top-level key\n // matching the first key in the path (schemaKeyPath[0]). This allows\n // key fields included in the written data to be saved in the cache\n // even if they are not selected explicitly in context.selectionSet.\n // Not being mentioned by context.selectionSet is convenient here,\n // since it means these extra fields cannot be affected by field\n // aliasing, which is why we can use extractKey instead of\n // context.readField for this extraction.\n extracted = extractKeyPath(object, schemaKeyPath, extractKey);\n }\n\n invariant(\n extracted !== void 0,\n `Missing field '${schemaKeyPath.join('.')}' while extracting keyFields from ${\n JSON.stringify(object)\n }`,\n );\n\n return extracted;\n },\n );\n\n return `${context.typename}:${JSON.stringify(keyObject)}`;\n });\n}\n\n// The keyArgs extraction process is roughly analogous to keyFields extraction,\n// but there are no aliases involved, missing fields are tolerated (by merely\n// omitting them from the key), and drawing from field.directives or variables\n// is allowed (in addition to drawing from the field's arguments object).\n// Concretely, these differences mean passing a different key path extractor\n// function to collectSpecifierPaths, reusing the shared extractKeyPath helper\n// wherever possible.\nexport function keyArgsFnFromSpecifier(specifier: KeySpecifier): KeyArgsFunction {\n const info = lookupSpecifierInfo(specifier);\n\n return info.keyArgsFn || (info.keyArgsFn = (args, {\n field,\n variables,\n fieldName,\n }) => {\n const collected = collectSpecifierPaths(specifier, keyPath => {\n const firstKey = keyPath[0];\n const firstChar = firstKey.charAt(0);\n\n if (firstChar === \"@\") {\n if (field && isNonEmptyArray(field.directives)) {\n const directiveName = firstKey.slice(1);\n // If the directive appears multiple times, only the first\n // occurrence's arguments will be used. TODO Allow repetition?\n // TODO Cache this work somehow, a la aliasMap?\n const d = field.directives.find(d => d.name.value === directiveName);\n // Fortunately argumentsObjectFromField works for DirectiveNode!\n const directiveArgs = d && argumentsObjectFromField(d, variables);\n // For directives without arguments (d defined, but directiveArgs ===\n // null), the presence or absence of the directive still counts as\n // part of the field key, so we return null in those cases. If no\n // directive with this name was found for this field (d undefined and\n // thus directiveArgs undefined), we return undefined, which causes\n // this value to be omitted from the key object returned by\n // collectSpecifierPaths.\n return directiveArgs && extractKeyPath(\n directiveArgs,\n // If keyPath.length === 1, this code calls extractKeyPath with an\n // empty path, which works because it uses directiveArgs as the\n // extracted value.\n keyPath.slice(1),\n );\n }\n // If the key started with @ but there was no corresponding directive,\n // we want to omit this value from the key object, not fall through to\n // treating @whatever as a normal argument name.\n return;\n }\n\n if (firstChar === \"$\") {\n const variableName = firstKey.slice(1);\n if (variables && hasOwn.call(variables, variableName)) {\n const varKeyPath = keyPath.slice(0);\n varKeyPath[0] = variableName;\n return extractKeyPath(variables, varKeyPath);\n }\n // If the key started with $ but there was no corresponding variable, we\n // want to omit this value from the key object, not fall through to\n // treating $whatever as a normal argument name.\n return;\n }\n\n if (args) {\n return extractKeyPath(args, keyPath);\n }\n });\n\n const suffix = JSON.stringify(collected);\n\n // If no arguments were passed to this field, and it didn't have any other\n // field key contributions from directives or variables, hide the empty\n // :{} suffix from the field key. However, a field passed no arguments can\n // still end up with a non-empty :{...} suffix if its key configuration\n // refers to directives or variables.\n if (args || suffix !== \"{}\") {\n fieldName += \":\" + suffix;\n }\n\n return fieldName;\n });\n}\n\nexport function collectSpecifierPaths(\n specifier: KeySpecifier,\n extractor: (path: string[]) => any,\n): Record<string, any> {\n // For each path specified by specifier, invoke the extractor, and repeatedly\n // merge the results together, with appropriate ancestor context.\n const merger = new DeepMerger;\n return getSpecifierPaths(specifier).reduce((collected, path) => {\n let toMerge = extractor(path);\n if (toMerge !== void 0) {\n // This path is not expected to contain array indexes, so the toMerge\n // reconstruction will not contain arrays. TODO Fix this?\n for (let i = path.length - 1; i >= 0; --i) {\n toMerge = { [path[i]]: toMerge };\n }\n collected = merger.merge(collected, toMerge);\n }\n return collected;\n }, Object.create(null));\n}\n\nexport function getSpecifierPaths(spec: KeySpecifier): string[][] {\n const info = lookupSpecifierInfo(spec);\n\n if (!info.paths) {\n const paths: string[][] = info.paths = [];\n const currentPath: string[] = [];\n\n spec.forEach((s, i) => {\n if (isArray(s)) {\n getSpecifierPaths(s).forEach(p => paths.push(currentPath.concat(p)));\n currentPath.length = 0;\n } else {\n currentPath.push(s);\n if (!isArray(spec[i + 1])) {\n paths.push(currentPath.slice(0));\n currentPath.length = 0;\n }\n }\n });\n }\n\n return info.paths!;\n}\n\nfunction extractKey<\n TObj extends Record<string, any>,\n TKey extends string,\n>(object: TObj, key: TKey): TObj[TKey] | undefined {\n return object[key];\n}\n\nexport function extractKeyPath(\n object: Record<string, any>,\n path: string[],\n extract?: typeof extractKey,\n): any {\n // For each key in path, extract the corresponding child property from obj,\n // flattening arrays if encountered (uncommon for keyFields and keyArgs, but\n // possible). The final result of path.reduce is normalized so unexpected leaf\n // objects have their keys safely sorted. That final result is difficult to\n // type as anything other than any. You're welcome to try to improve the\n // return type, but keep in mind extractKeyPath is not a public function\n // (exported only for testing), so the effort may not be worthwhile unless the\n // limited set of actual callers (see above) pass arguments that TypeScript\n // can statically type. If we know only that path is some array of strings\n // (and not, say, a specific tuple of statically known strings), any (or\n // possibly unknown) is the honest answer.\n extract = extract || extractKey;\n return normalize(path.reduce(function reducer(obj, key): any {\n return isArray(obj)\n ? obj.map(child => reducer(child, key))\n : obj && extract!(obj, key);\n }, object));\n}\n\nfunction normalize<T>(value: T): T {\n // Usually the extracted value will be a scalar value, since most primary\n // key fields are scalar, but just in case we get an object or an array, we\n // need to do some normalization of the order of (nested) keys.\n if (isNonNullObject(value)) {\n if (isArray(value)) {\n return value.map(normalize) as any;\n }\n return collectSpecifierPaths(\n Object.keys(value).sort(),\n path => extractKeyPath(value, path),\n ) as T;\n }\n return value;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-canon.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/object-canon.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"object-canon.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/object-canon.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC;AA0EjC,qBAAa,WAAW;IAGtB,OAAO,CAAC,KAAK,CAAiD;IAG9D,OAAO,CAAC,IAAI,CAIM;IAEX,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO;IAMnC,OAAO,CAAC,MAAM,CAAiC;IACxC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAWpB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC;IAuE5B,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,UAAU,CAAqC;IAGvD,SAAgB,KAAK,KAAkB;CACxC;AAUD,eAAO,MAAM,kBAAkB,WAAkC,GAAG,KAAG,MAAM;;CAkB3E,CAAC;AAMH,iBAAS,uBAAuB,SAG/B"}
|
|
@@ -2,9 +2,10 @@ import { __assign } from "tslib";
|
|
|
2
2
|
import "../../utilities/globals/index.js";
|
|
3
3
|
import { Trie } from "@wry/trie";
|
|
4
4
|
import { canUseWeakMap, canUseWeakSet, isNonNullObject as isObjectOrArray, } from "../../utilities/index.js";
|
|
5
|
+
import { isArray } from "./helpers.js";
|
|
5
6
|
function shallowCopy(value) {
|
|
6
7
|
if (isObjectOrArray(value)) {
|
|
7
|
-
return
|
|
8
|
+
return isArray(value)
|
|
8
9
|
? value.slice(0)
|
|
9
10
|
: __assign({ __proto__: Object.getPrototypeOf(value) }, value);
|
|
10
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-canon.js","sourceRoot":"","sources":["../../../src/cache/inmemory/object-canon.ts"],"names":[],"mappings":"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","sourcesContent":["import \"../../utilities/globals\";\n\nimport { Trie } from \"@wry/trie\";\nimport {\n canUseWeakMap,\n canUseWeakSet,\n isNonNullObject as isObjectOrArray,\n} from \"../../utilities\";\n\nfunction shallowCopy<T>(value: T): T {\n if (isObjectOrArray(value)) {\n return Array.isArray(value)\n ? value.slice(0) as any as T\n : { __proto__: Object.getPrototypeOf(value), ...value };\n }\n return value;\n}\n\n// When programmers talk about the \"canonical form\" of an object, they\n// usually have the following meaning in mind, which I've copied from\n// https://en.wiktionary.org/wiki/canonical_form:\n//\n// 1. A standard or normal presentation of a mathematical entity [or\n// object]. A canonical form is an element of a set of representatives\n// of equivalence classes of forms such that there is a function or\n// procedure which projects every element of each equivalence class\n// onto that one element, the canonical form of that equivalence\n// class. The canonical form is expected to be simpler than the rest of\n// the forms in some way.\n//\n// That's a long-winded way of saying any two objects that have the same\n// canonical form may be considered equivalent, even if they are !==,\n// which usually means the objects are structurally equivalent (deeply\n// equal), but don't necessarily use the same memory.\n//\n// Like a literary or musical canon, this ObjectCanon class represents a\n// collection of unique canonical items (JavaScript objects), with the\n// important property that canon.admit(a) === canon.admit(b) if a and b\n// are deeply equal to each other. In terms of the definition above, the\n// canon.admit method is the \"function or procedure which projects every\"\n// object \"onto that one element, the canonical form.\"\n//\n// In the worst case, the canonicalization process may involve looking at\n// every property in the provided object tree, so it takes the same order\n// of time as deep equality checking. Fortunately, already-canonicalized\n// objects are returned immediately from canon.admit, so the presence of\n// canonical subtrees tends to speed up canonicalization.\n//\n// Since consumers of canonical objects can check for deep equality in\n// constant time, canonicalizing cache results can massively improve the\n// performance of application code that skips re-rendering unchanged\n// results, such as \"pure\" UI components in a framework like React.\n//\n// Of course, since canonical objects may be shared widely between\n// unrelated consumers, it's important to think of them as immutable, even\n// though they are not actually frozen with Object.freeze in production,\n// due to the extra performance overhead that comes with frozen objects.\n//\n// Custom scalar objects whose internal class name is neither Array nor\n// Object can be included safely in the admitted tree, but they will not\n// be replaced with a canonical version (to put it another way, they are\n// assumed to be canonical already).\n//\n// If we ignore custom objects, no detection of cycles or repeated object\n// references is currently required by the StoreReader class, since\n// GraphQL result objects are JSON-serializable trees (and thus contain\n// neither cycles nor repeated subtrees), so we can avoid the complexity\n// of keeping track of objects we've already seen during the recursion of\n// the admit method.\n//\n// In the future, we may consider adding additional cases to the switch\n// statement to handle other common object types, such as \"[object Date]\"\n// objects, as needed.\nexport class ObjectCanon {\n // Set of all canonical objects this ObjectCanon has admitted, allowing\n // canon.admit to return previously-canonicalized objects immediately.\n private known = new (canUseWeakSet ? WeakSet : Set)<object>();\n\n // Efficient storage/lookup structure for canonical objects.\n private pool = new Trie<{\n array?: any[];\n object?: Record<string, any>;\n keys?: SortedKeysInfo;\n }>(canUseWeakMap);\n\n public isKnown(value: any): boolean {\n return isObjectOrArray(value) && this.known.has(value);\n }\n\n // Make the ObjectCanon assume this value has already been\n // canonicalized.\n private passes = new WeakMap<object, object>();\n public pass<T>(value: T): T;\n public pass(value: any) {\n if (isObjectOrArray(value)) {\n const copy = shallowCopy(value);\n this.passes.set(copy, value);\n return copy;\n }\n return value;\n }\n\n // Returns the canonical version of value.\n public admit<T>(value: T): T;\n public admit(value: any) {\n if (isObjectOrArray(value)) {\n const original = this.passes.get(value);\n if (original) return original;\n\n const proto = Object.getPrototypeOf(value);\n switch (proto) {\n case Array.prototype: {\n if (this.known.has(value)) return value;\n const array: any[] = (value as any[]).map(this.admit, this);\n // Arrays are looked up in the Trie using their recursively\n // canonicalized elements, and the known version of the array is\n // preserved as node.array.\n const node = this.pool.lookupArray(array);\n if (!node.array) {\n this.known.add(node.array = array);\n // Since canonical arrays may be shared widely between\n // unrelated consumers, it's important to regard them as\n // immutable, even if they are not frozen in production.\n if (__DEV__) {\n Object.freeze(array);\n }\n }\n return node.array;\n }\n\n case null:\n case Object.prototype: {\n if (this.known.has(value)) return value;\n const proto = Object.getPrototypeOf(value);\n const array = [proto];\n const keys = this.sortedKeys(value);\n array.push(keys.json);\n const firstValueIndex = array.length;\n keys.sorted.forEach(key => {\n array.push(this.admit((value as any)[key]));\n });\n // Objects are looked up in the Trie by their prototype (which\n // is *not* recursively canonicalized), followed by a JSON\n // representation of their (sorted) keys, followed by the\n // sequence of recursively canonicalized values corresponding to\n // those keys. To keep the final results unambiguous with other\n // sequences (such as arrays that just happen to contain [proto,\n // keys.json, value1, value2, ...]), the known version of the\n // object is stored as node.object.\n const node = this.pool.lookupArray(array);\n if (!node.object) {\n const obj = node.object = Object.create(proto);\n this.known.add(obj);\n keys.sorted.forEach((key, i) => {\n obj[key] = array[firstValueIndex + i];\n });\n // Since canonical objects may be shared widely between\n // unrelated consumers, it's important to regard them as\n // immutable, even if they are not frozen in production.\n if (__DEV__) {\n Object.freeze(obj);\n }\n }\n return node.object;\n }\n }\n }\n return value;\n }\n\n // It's worthwhile to cache the sorting of arrays of strings, since the\n // same initial unsorted arrays tend to be encountered many times.\n // Fortunately, we can reuse the Trie machinery to look up the sorted\n // arrays in linear time (which is faster than sorting large arrays).\n private sortedKeys(obj: object) {\n const keys = Object.keys(obj);\n const node = this.pool.lookupArray(keys);\n if (!node.keys) {\n keys.sort();\n const json = JSON.stringify(keys);\n if (!(node.keys = this.keysByJSON.get(json))) {\n this.keysByJSON.set(json, node.keys = { sorted: keys, json });\n }\n }\n return node.keys;\n }\n // Arrays that contain the same elements in a different order can share\n // the same SortedKeysInfo object, to save memory.\n private keysByJSON = new Map<string, SortedKeysInfo>();\n\n // This has to come last because it depends on keysByJSON.\n public readonly empty = this.admit({});\n}\n\ntype SortedKeysInfo = {\n sorted: string[];\n json: string;\n};\n\n// Since the keys of canonical objects are always created in lexicographically\n// sorted order, we can use the ObjectCanon to implement a fast and stable\n// version of JSON.stringify, which automatically sorts object keys.\nexport const canonicalStringify = Object.assign(function (value: any): string {\n if (isObjectOrArray(value)) {\n if (stringifyCanon === void 0) {\n resetCanonicalStringify();\n }\n const canonical = stringifyCanon.admit(value);\n let json = stringifyCache.get(canonical);\n if (json === void 0) {\n stringifyCache.set(\n canonical,\n json = JSON.stringify(canonical),\n );\n }\n return json;\n }\n return JSON.stringify(value);\n}, {\n reset: resetCanonicalStringify,\n});\n\n// Can be reset by calling canonicalStringify.reset().\nlet stringifyCanon: ObjectCanon;\nlet stringifyCache: WeakMap<object, string>;\n\nfunction resetCanonicalStringify() {\n stringifyCanon = new ObjectCanon;\n stringifyCache = new (canUseWeakMap ? WeakMap : Map)();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"object-canon.js","sourceRoot":"","sources":["../../../src/cache/inmemory/object-canon.ts"],"names":[],"mappings":"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","sourcesContent":["import \"../../utilities/globals\";\n\nimport { Trie } from \"@wry/trie\";\nimport {\n canUseWeakMap,\n canUseWeakSet,\n isNonNullObject as isObjectOrArray,\n} from \"../../utilities\";\nimport { isArray } from \"./helpers\";\n\nfunction shallowCopy<T>(value: T): T {\n if (isObjectOrArray(value)) {\n return isArray(value)\n ? value.slice(0) as any as T\n : { __proto__: Object.getPrototypeOf(value), ...value };\n }\n return value;\n}\n\n// When programmers talk about the \"canonical form\" of an object, they\n// usually have the following meaning in mind, which I've copied from\n// https://en.wiktionary.org/wiki/canonical_form:\n//\n// 1. A standard or normal presentation of a mathematical entity [or\n// object]. A canonical form is an element of a set of representatives\n// of equivalence classes of forms such that there is a function or\n// procedure which projects every element of each equivalence class\n// onto that one element, the canonical form of that equivalence\n// class. The canonical form is expected to be simpler than the rest of\n// the forms in some way.\n//\n// That's a long-winded way of saying any two objects that have the same\n// canonical form may be considered equivalent, even if they are !==,\n// which usually means the objects are structurally equivalent (deeply\n// equal), but don't necessarily use the same memory.\n//\n// Like a literary or musical canon, this ObjectCanon class represents a\n// collection of unique canonical items (JavaScript objects), with the\n// important property that canon.admit(a) === canon.admit(b) if a and b\n// are deeply equal to each other. In terms of the definition above, the\n// canon.admit method is the \"function or procedure which projects every\"\n// object \"onto that one element, the canonical form.\"\n//\n// In the worst case, the canonicalization process may involve looking at\n// every property in the provided object tree, so it takes the same order\n// of time as deep equality checking. Fortunately, already-canonicalized\n// objects are returned immediately from canon.admit, so the presence of\n// canonical subtrees tends to speed up canonicalization.\n//\n// Since consumers of canonical objects can check for deep equality in\n// constant time, canonicalizing cache results can massively improve the\n// performance of application code that skips re-rendering unchanged\n// results, such as \"pure\" UI components in a framework like React.\n//\n// Of course, since canonical objects may be shared widely between\n// unrelated consumers, it's important to think of them as immutable, even\n// though they are not actually frozen with Object.freeze in production,\n// due to the extra performance overhead that comes with frozen objects.\n//\n// Custom scalar objects whose internal class name is neither Array nor\n// Object can be included safely in the admitted tree, but they will not\n// be replaced with a canonical version (to put it another way, they are\n// assumed to be canonical already).\n//\n// If we ignore custom objects, no detection of cycles or repeated object\n// references is currently required by the StoreReader class, since\n// GraphQL result objects are JSON-serializable trees (and thus contain\n// neither cycles nor repeated subtrees), so we can avoid the complexity\n// of keeping track of objects we've already seen during the recursion of\n// the admit method.\n//\n// In the future, we may consider adding additional cases to the switch\n// statement to handle other common object types, such as \"[object Date]\"\n// objects, as needed.\nexport class ObjectCanon {\n // Set of all canonical objects this ObjectCanon has admitted, allowing\n // canon.admit to return previously-canonicalized objects immediately.\n private known = new (canUseWeakSet ? WeakSet : Set)<object>();\n\n // Efficient storage/lookup structure for canonical objects.\n private pool = new Trie<{\n array?: any[];\n object?: Record<string, any>;\n keys?: SortedKeysInfo;\n }>(canUseWeakMap);\n\n public isKnown(value: any): boolean {\n return isObjectOrArray(value) && this.known.has(value);\n }\n\n // Make the ObjectCanon assume this value has already been\n // canonicalized.\n private passes = new WeakMap<object, object>();\n public pass<T>(value: T): T;\n public pass(value: any) {\n if (isObjectOrArray(value)) {\n const copy = shallowCopy(value);\n this.passes.set(copy, value);\n return copy;\n }\n return value;\n }\n\n // Returns the canonical version of value.\n public admit<T>(value: T): T;\n public admit(value: any) {\n if (isObjectOrArray(value)) {\n const original = this.passes.get(value);\n if (original) return original;\n\n const proto = Object.getPrototypeOf(value);\n switch (proto) {\n case Array.prototype: {\n if (this.known.has(value)) return value;\n const array: any[] = (value as any[]).map(this.admit, this);\n // Arrays are looked up in the Trie using their recursively\n // canonicalized elements, and the known version of the array is\n // preserved as node.array.\n const node = this.pool.lookupArray(array);\n if (!node.array) {\n this.known.add(node.array = array);\n // Since canonical arrays may be shared widely between\n // unrelated consumers, it's important to regard them as\n // immutable, even if they are not frozen in production.\n if (__DEV__) {\n Object.freeze(array);\n }\n }\n return node.array;\n }\n\n case null:\n case Object.prototype: {\n if (this.known.has(value)) return value;\n const proto = Object.getPrototypeOf(value);\n const array = [proto];\n const keys = this.sortedKeys(value);\n array.push(keys.json);\n const firstValueIndex = array.length;\n keys.sorted.forEach(key => {\n array.push(this.admit((value as any)[key]));\n });\n // Objects are looked up in the Trie by their prototype (which\n // is *not* recursively canonicalized), followed by a JSON\n // representation of their (sorted) keys, followed by the\n // sequence of recursively canonicalized values corresponding to\n // those keys. To keep the final results unambiguous with other\n // sequences (such as arrays that just happen to contain [proto,\n // keys.json, value1, value2, ...]), the known version of the\n // object is stored as node.object.\n const node = this.pool.lookupArray(array);\n if (!node.object) {\n const obj = node.object = Object.create(proto);\n this.known.add(obj);\n keys.sorted.forEach((key, i) => {\n obj[key] = array[firstValueIndex + i];\n });\n // Since canonical objects may be shared widely between\n // unrelated consumers, it's important to regard them as\n // immutable, even if they are not frozen in production.\n if (__DEV__) {\n Object.freeze(obj);\n }\n }\n return node.object;\n }\n }\n }\n return value;\n }\n\n // It's worthwhile to cache the sorting of arrays of strings, since the\n // same initial unsorted arrays tend to be encountered many times.\n // Fortunately, we can reuse the Trie machinery to look up the sorted\n // arrays in linear time (which is faster than sorting large arrays).\n private sortedKeys(obj: object) {\n const keys = Object.keys(obj);\n const node = this.pool.lookupArray(keys);\n if (!node.keys) {\n keys.sort();\n const json = JSON.stringify(keys);\n if (!(node.keys = this.keysByJSON.get(json))) {\n this.keysByJSON.set(json, node.keys = { sorted: keys, json });\n }\n }\n return node.keys;\n }\n // Arrays that contain the same elements in a different order can share\n // the same SortedKeysInfo object, to save memory.\n private keysByJSON = new Map<string, SortedKeysInfo>();\n\n // This has to come last because it depends on keysByJSON.\n public readonly empty = this.admit({});\n}\n\ntype SortedKeysInfo = {\n sorted: string[];\n json: string;\n};\n\n// Since the keys of canonical objects are always created in lexicographically\n// sorted order, we can use the ObjectCanon to implement a fast and stable\n// version of JSON.stringify, which automatically sorts object keys.\nexport const canonicalStringify = Object.assign(function (value: any): string {\n if (isObjectOrArray(value)) {\n if (stringifyCanon === void 0) {\n resetCanonicalStringify();\n }\n const canonical = stringifyCanon.admit(value);\n let json = stringifyCache.get(canonical);\n if (json === void 0) {\n stringifyCache.set(\n canonical,\n json = JSON.stringify(canonical),\n );\n }\n return json;\n }\n return JSON.stringify(value);\n}, {\n reset: resetCanonicalStringify,\n});\n\n// Can be reset by calling canonicalStringify.reset().\nlet stringifyCanon: ObjectCanon;\nlet stringifyCache: WeakMap<object, string>;\n\nfunction resetCanonicalStringify() {\n stringifyCanon = new ObjectCanon;\n stringifyCache = new (canUseWeakMap ? WeakMap : Map)();\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { WriteContext } from './writeToStore';
|
|
|
7
7
|
export declare type TypePolicies = {
|
|
8
8
|
[__typename: string]: TypePolicy;
|
|
9
9
|
};
|
|
10
|
-
export declare type KeySpecifier =
|
|
10
|
+
export declare type KeySpecifier = ReadonlyArray<string | KeySpecifier>;
|
|
11
11
|
export declare type KeyFieldsContext = {
|
|
12
12
|
typename: string | undefined;
|
|
13
13
|
storeObject: StoreObject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/policies.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,WAAW,EAEX,UAAU,EACV,WAAW,EAEX,SAAS,EACT,WAAW,EAIZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,QAAQ,EACR,SAAS,EAET,sBAAsB,EACvB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../../../src/cache/inmemory/policies.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __assign, __rest } from "tslib";
|
|
2
2
|
import { invariant, InvariantError } from "../../utilities/globals/index.js";
|
|
3
3
|
import { storeKeyNameFromField, argumentsObjectFromField, isReference, getStoreKeyName, isNonNullObject, stringifyForDisplay, } from "../../utilities/index.js";
|
|
4
|
-
import { hasOwn, fieldNameFromStoreName, storeValueIsStoreObject, selectionSetMatchesResult, TypeOrFieldNameRegExp, defaultDataIdFromObject, } from "./helpers.js";
|
|
4
|
+
import { hasOwn, fieldNameFromStoreName, storeValueIsStoreObject, selectionSetMatchesResult, TypeOrFieldNameRegExp, defaultDataIdFromObject, isArray, } from "./helpers.js";
|
|
5
5
|
import { cacheSlot } from "./reactiveVars.js";
|
|
6
6
|
import { canonicalStringify } from "./object-canon.js";
|
|
7
7
|
import { keyArgsFnFromSpecifier, keyFieldsFnFromSpecifier } from "./key-extractor.js";
|
|
@@ -60,7 +60,7 @@ var Policies = (function () {
|
|
|
60
60
|
var keyFn = policy && policy.keyFn || this.config.dataIdFromObject;
|
|
61
61
|
while (keyFn) {
|
|
62
62
|
var specifierOrId = keyFn(object, context);
|
|
63
|
-
if (
|
|
63
|
+
if (isArray(specifierOrId)) {
|
|
64
64
|
keyFn = keyFieldsFnFromSpecifier(specifierOrId);
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
@@ -103,7 +103,7 @@ var Policies = (function () {
|
|
|
103
103
|
setMerge(existing, incoming.merge);
|
|
104
104
|
existing.keyFn =
|
|
105
105
|
keyFields === false ? nullKeyFieldsFn :
|
|
106
|
-
|
|
106
|
+
isArray(keyFields) ? keyFieldsFnFromSpecifier(keyFields) :
|
|
107
107
|
typeof keyFields === "function" ? keyFields :
|
|
108
108
|
existing.keyFn;
|
|
109
109
|
if (fields) {
|
|
@@ -117,7 +117,7 @@ var Policies = (function () {
|
|
|
117
117
|
var keyArgs = incoming.keyArgs, read = incoming.read, merge = incoming.merge;
|
|
118
118
|
existing.keyFn =
|
|
119
119
|
keyArgs === false ? simpleKeyArgsFn :
|
|
120
|
-
|
|
120
|
+
isArray(keyArgs) ? keyArgsFnFromSpecifier(keyArgs) :
|
|
121
121
|
typeof keyArgs === "function" ? keyArgs :
|
|
122
122
|
existing.keyFn;
|
|
123
123
|
if (typeof read === "function") {
|
|
@@ -262,7 +262,7 @@ var Policies = (function () {
|
|
|
262
262
|
var args = argsFromFieldSpecifier(fieldSpec);
|
|
263
263
|
while (keyFn) {
|
|
264
264
|
var specifierOrString = keyFn(args, context);
|
|
265
|
-
if (
|
|
265
|
+
if (isArray(specifierOrString)) {
|
|
266
266
|
keyFn = keyArgsFnFromSpecifier(specifierOrString);
|
|
267
267
|
}
|
|
268
268
|
else {
|
|
@@ -384,7 +384,7 @@ export function normalizeReadFieldOptions(readFieldArgs, objectOrReference, vari
|
|
|
384
384
|
}
|
|
385
385
|
function makeMergeObjectsFunction(store) {
|
|
386
386
|
return function mergeObjects(existing, incoming) {
|
|
387
|
-
if (
|
|
387
|
+
if (isArray(existing) || isArray(incoming)) {
|
|
388
388
|
throw __DEV__ ? new InvariantError("Cannot automatically merge arrays") : new InvariantError(4);
|
|
389
389
|
}
|
|
390
390
|
if (isNonNullObject(existing) &&
|