@isograph/react 0.0.0-main-3a36e9fb → 0.0.0-main-beecd3bf

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.
Files changed (52) hide show
  1. package/dist/core/FragmentReference.js +1 -1
  2. package/dist/core/IsographEnvironment.d.ts +7 -5
  3. package/dist/core/IsographEnvironment.d.ts.map +1 -1
  4. package/dist/core/IsographEnvironment.js +7 -15
  5. package/dist/core/cache.d.ts +6 -2
  6. package/dist/core/cache.d.ts.map +1 -1
  7. package/dist/core/cache.js +75 -19
  8. package/dist/core/check.d.ts +1 -1
  9. package/dist/core/check.d.ts.map +1 -1
  10. package/dist/core/check.js +9 -4
  11. package/dist/core/entrypoint.d.ts +2 -0
  12. package/dist/core/entrypoint.d.ts.map +1 -1
  13. package/dist/core/garbageCollection.d.ts +2 -1
  14. package/dist/core/garbageCollection.d.ts.map +1 -1
  15. package/dist/core/garbageCollection.js +45 -11
  16. package/dist/core/logging.d.ts +2 -2
  17. package/dist/core/logging.d.ts.map +1 -1
  18. package/dist/core/makeNetworkRequest.d.ts.map +1 -1
  19. package/dist/core/makeNetworkRequest.js +8 -2
  20. package/dist/core/read.d.ts +4 -3
  21. package/dist/core/read.d.ts.map +1 -1
  22. package/dist/core/read.js +13 -10
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -2
  26. package/dist/react/useImperativeReference.js +1 -1
  27. package/package.json +4 -4
  28. package/schema.graphql +1 -0
  29. package/src/core/FragmentReference.ts +1 -1
  30. package/src/core/IsographEnvironment.ts +15 -25
  31. package/src/core/cache.ts +106 -25
  32. package/src/core/check.ts +10 -5
  33. package/src/core/entrypoint.ts +2 -0
  34. package/src/core/garbageCollection.ts +71 -20
  35. package/src/core/logging.ts +2 -2
  36. package/src/core/makeNetworkRequest.ts +8 -1
  37. package/src/core/read.ts +25 -16
  38. package/src/index.ts +0 -1
  39. package/src/react/useImperativeReference.ts +1 -1
  40. package/src/tests/__isograph/Query/meName/entrypoint.ts +1 -0
  41. package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +1 -0
  42. package/src/tests/__isograph/Query/nodeField/entrypoint.ts +1 -0
  43. package/src/tests/__isograph/Query/subquery/entrypoint.ts +67 -0
  44. package/src/tests/__isograph/Query/subquery/output_type.ts +3 -0
  45. package/src/tests/__isograph/Query/subquery/param_type.ts +12 -0
  46. package/src/tests/__isograph/Query/subquery/parameters_type.ts +3 -0
  47. package/src/tests/__isograph/Query/subquery/resolver_reader.ts +47 -0
  48. package/src/tests/__isograph/iso.ts +10 -0
  49. package/src/tests/garbageCollection.test.ts +43 -36
  50. package/src/tests/meNameSuccessor.ts +5 -0
  51. package/src/tests/nodeQuery.ts +2 -0
  52. package/src/tests/normalizeData.test.ts +120 -0
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.maybeMakeNetworkRequest = maybeMakeNetworkRequest;
4
4
  exports.makeNetworkRequest = makeNetworkRequest;
5
5
  const garbageCollection_1 = require("./garbageCollection");
6
+ const IsographEnvironment_1 = require("./IsographEnvironment");
6
7
  const PromiseWrapper_1 = require("./PromiseWrapper");
7
8
  const cache_1 = require("./cache");
8
9
  const logging_1 = require("./logging");
@@ -17,7 +18,10 @@ function maybeMakeNetworkRequest(environment, artifact, variables, shouldFetch)
17
18
  return [(0, PromiseWrapper_1.wrapResolvedValue)(undefined), () => { }];
18
19
  }
19
20
  case 'IfNecessary': {
20
- const result = (0, check_1.check)(environment, artifact.networkRequestInfo.normalizationAst, variables);
21
+ const result = (0, check_1.check)(environment, artifact.networkRequestInfo.normalizationAst, variables, {
22
+ __link: IsographEnvironment_1.ROOT_ID,
23
+ __typename: artifact.concreteType,
24
+ });
21
25
  if (result.kind === 'EnoughData') {
22
26
  return [(0, PromiseWrapper_1.wrapResolvedValue)(undefined), () => { }];
23
27
  }
@@ -57,12 +61,14 @@ function makeNetworkRequest(environment, artifact, variables) {
57
61
  });
58
62
  }
59
63
  if (status.kind === 'UndisposedIncomplete') {
64
+ const root = { __link: IsographEnvironment_1.ROOT_ID, __typename: artifact.concreteType };
60
65
  (0, cache_1.normalizeData)(environment, artifact.networkRequestInfo.normalizationAst, (_a = networkResponse.data) !== null && _a !== void 0 ? _a : {}, variables, artifact.kind === 'Entrypoint'
61
66
  ? artifact.readerWithRefetchQueries.nestedRefetchQueries
62
- : []);
67
+ : [], root);
63
68
  const retainedQuery = {
64
69
  normalizationAst: artifact.networkRequestInfo.normalizationAst,
65
70
  variables,
71
+ root,
66
72
  };
67
73
  status = {
68
74
  kind: 'UndisposedComplete',
@@ -1,7 +1,8 @@
1
+ import { type EncounteredIds } from './cache';
1
2
  import { FragmentReference, ExtractData } from './FragmentReference';
2
- import { DataId, IsographEnvironment, type Link } from './IsographEnvironment';
3
+ import { IsographEnvironment, type Link } from './IsographEnvironment';
3
4
  export type WithEncounteredRecords<T> = {
4
- readonly encounteredRecords: Set<DataId>;
5
+ readonly encounteredRecords: EncounteredIds;
5
6
  readonly item: ExtractData<T>;
6
7
  };
7
8
  export declare function readButDoNotEvaluate<TReadFromStore extends {
@@ -11,7 +12,7 @@ export declare function readButDoNotEvaluate<TReadFromStore extends {
11
12
  export type ReadDataResult<TReadFromStore> = {
12
13
  readonly kind: 'Success';
13
14
  readonly data: ExtractData<TReadFromStore>;
14
- readonly encounteredRecords: Set<DataId>;
15
+ readonly encounteredRecords: EncounteredIds;
15
16
  } | {
16
17
  readonly kind: 'MissingData';
17
18
  readonly reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/core/read.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,iBAAiB,EAEjB,WAAW,EAEZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,MAAM,EAGN,mBAAmB,EACnB,KAAK,IAAI,EACV,MAAM,uBAAuB,CAAC;AAe/B,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAE3D,WAAW,EAAE,mBAAmB,EAChC,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,EAC7D,qBAAqB,EAAE,2BAA2B,GACjD,sBAAsB,CAAC,cAAc,CAAC,CAkDxC;AAED,MAAM,MAAM,cAAc,CAAC,cAAc,IACrC;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC1C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B,CAAC;AAyjBN,MAAM,MAAM,2BAA2B,GAAG;IACxC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oCAAoC,CAClD,qBAAqB,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,GAClE,2BAA2B,CAK7B"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/core/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAMjB,OAAO,EACL,iBAAiB,EAEjB,WAAW,EAEZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,mBAAmB,EACnB,KAAK,IAAI,EACV,MAAM,uBAAuB,CAAC;AAe/B,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,QAAQ,CAAC,kBAAkB,EAAE,cAAc,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAE3D,WAAW,EAAE,mBAAmB,EAChC,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,EAC7D,qBAAqB,EAAE,2BAA2B,GACjD,sBAAsB,CAAC,cAAc,CAAC,CAkDxC;AAED,MAAM,MAAM,cAAc,CAAC,cAAc,IACrC;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,cAAc,CAAC;CAC7C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B,CAAC;AA+jBN,MAAM,MAAM,2BAA2B,GAAG;IACxC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oCAAoC,CAClD,qBAAqB,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,GAClE,2BAA2B,CAK7B"}
package/dist/core/read.js CHANGED
@@ -11,7 +11,7 @@ const logging_1 = require("./logging");
11
11
  const check_1 = require("./check");
12
12
  function readButDoNotEvaluate(environment, fragmentReference, networkRequestOptions) {
13
13
  var _a;
14
- const mutableEncounteredRecords = new Set();
14
+ const mutableEncounteredRecords = new Map();
15
15
  const readerWithRefetchQueries = (0, PromiseWrapper_1.readPromise)(fragmentReference.readerWithRefetchQueries);
16
16
  const response = readData(environment, readerWithRefetchQueries.readerArtifact.readerAst, fragmentReference.root, (_a = fragmentReference.variables) !== null && _a !== void 0 ? _a : {}, readerWithRefetchQueries.nestedRefetchQueries, fragmentReference.networkRequest, networkRequestOptions, mutableEncounteredRecords);
17
17
  (0, logging_1.logMessage)(environment, {
@@ -47,8 +47,9 @@ function readButDoNotEvaluate(environment, fragmentReference, networkRequestOpti
47
47
  }
48
48
  function readData(environment, ast, root, variables, nestedRefetchQueries, networkRequest, networkRequestOptions, mutableEncounteredRecords) {
49
49
  var _a, _b, _c, _d, _e;
50
- mutableEncounteredRecords.add(root.__link);
51
- let storeRecord = environment.store[root.__link];
50
+ const encounteredIds = (0, cache_1.insertIfNotExists)(mutableEncounteredRecords, root.__typename);
51
+ encounteredIds.add(root.__link);
52
+ let storeRecord = (_a = environment.store[root.__typename]) === null || _a === void 0 ? void 0 : _a[root.__link];
52
53
  if (storeRecord === undefined) {
53
54
  return {
54
55
  kind: 'MissingData',
@@ -78,7 +79,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
78
79
  recordLink: root,
79
80
  };
80
81
  }
81
- target[(_a = field.alias) !== null && _a !== void 0 ? _a : field.fieldName] = value;
82
+ target[(_b = field.alias) !== null && _b !== void 0 ? _b : field.fieldName] = value;
82
83
  break;
83
84
  }
84
85
  case 'Linked': {
@@ -120,7 +121,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
120
121
  }
121
122
  results.push(result.data);
122
123
  }
123
- target[(_b = field.alias) !== null && _b !== void 0 ? _b : field.fieldName] = results;
124
+ target[(_c = field.alias) !== null && _c !== void 0 ? _c : field.fieldName] = results;
124
125
  break;
125
126
  }
126
127
  let link = (0, IsographEnvironment_1.assertLink)(value);
@@ -153,8 +154,8 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
153
154
  }
154
155
  if (link === undefined) {
155
156
  // TODO make this configurable, and also generated and derived from the schema
156
- const missingFieldHandler = (_c = environment.missingFieldHandler) !== null && _c !== void 0 ? _c : IsographEnvironment_1.defaultMissingFieldHandler;
157
- const altLink = missingFieldHandler(storeRecord, root, field.fieldName, field.arguments, variables);
157
+ const missingFieldHandler = environment.missingFieldHandler;
158
+ const altLink = missingFieldHandler === null || missingFieldHandler === void 0 ? void 0 : missingFieldHandler(storeRecord, root, field.fieldName, field.arguments, variables);
158
159
  (0, logging_1.logMessage)(environment, {
159
160
  kind: 'MissingFieldHandlerCalled',
160
161
  root,
@@ -303,7 +304,9 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
303
304
  writeQueryArgsToVariables(localVariables, field.queryArguments, variables);
304
305
  return [
305
306
  // Stable id
306
- root.__link +
307
+ root.__typename +
308
+ ':' +
309
+ root.__link +
307
310
  '/' +
308
311
  field.name +
309
312
  '/' +
@@ -323,7 +326,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
323
326
  .nestedRefetchQueries,
324
327
  }),
325
328
  // TODO localVariables is not guaranteed to have an id field
326
- root: { __link: localVariables.id },
329
+ root,
327
330
  variables: localVariables,
328
331
  networkRequest,
329
332
  };
@@ -358,7 +361,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
358
361
  kind: 'FragmentReference',
359
362
  readerWithRefetchQueries: (0, PromiseWrapper_1.wrapPromise)(readerWithRefetchPromise),
360
363
  // TODO localVariables is not guaranteed to have an id field
361
- root: { __link: localVariables.id },
364
+ root,
362
365
  variables: localVariables,
363
366
  networkRequest,
364
367
  };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { retainQuery, unretainQuery, type RetainedQuery, garbageCollectEnvironme
2
2
  export { type PromiseWrapper, readPromise, getPromiseState, wrapResolvedValue, wrapPromise, } from './core/PromiseWrapper';
3
3
  export { subscribe, normalizeData } from './core/cache';
4
4
  export { makeNetworkRequest } from './core/makeNetworkRequest';
5
- export { ROOT_ID, type DataId, type DataTypeValue, type IsographEnvironment, type IsographNetworkFunction, type IsographStore, type Link, type StoreRecord, createIsographEnvironment, createIsographStore, defaultMissingFieldHandler, } from './core/IsographEnvironment';
5
+ export { ROOT_ID, type DataId, type DataTypeValue, type IsographEnvironment, type IsographNetworkFunction, type IsographStore, type Link, type StoreRecord, createIsographEnvironment, createIsographStore, } from './core/IsographEnvironment';
6
6
  export { type EagerReaderArtifact, type ComponentReaderArtifact, type RefetchReaderArtifact, type ReaderAst, type ReaderAstNode, type ReaderLinkedField, type ReaderNonLoadableResolverField, type ReaderScalarField, type TopLevelReaderArtifact, type LoadableField, type ResolverFirstParameter, } from './core/reader';
7
7
  export { type NormalizationAst, type NormalizationAstNode, type NormalizationLinkedField, type NormalizationScalarField, type IsographEntrypoint, assertIsEntrypoint, type RefetchQueryNormalizationArtifact, type RefetchQueryNormalizationArtifactWrapper, type ExtractProps, type ExtractReadFromStore, type ExtractResolverResult, type NetworkRequestInfo, } from './core/entrypoint';
8
8
  export { readButDoNotEvaluate } from './core/read';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,KAAK,aAAa,EAClB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,OAAO,EACP,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,8BAA8B,EACnC,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,KAAK,iCAAiC,EACtC,KAAK,wCAAwC,EAC7C,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,8BAA8B,EACnC,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,UAAU,EACV,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7E,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,gCAAgC,GACtC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oDAAoD,CAAC;AACvG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,KAAK,aAAa,EAClB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,OAAO,EACP,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,IAAI,EACT,KAAK,WAAW,EAChB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,8BAA8B,EACnC,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,kBAAkB,EAClB,KAAK,iCAAiC,EACtC,KAAK,wCAAwC,EAC7C,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,8BAA8B,EACnC,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,UAAU,EACV,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7E,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,gCAAgC,GACtC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,iCAAiC,EAAE,MAAM,oDAAoD,CAAC;AACvG,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useImperativeLoadableField = exports.useConnectionSpecPagination = exports.useSkipLimitPagination = exports.useImperativeExposedMutationField = exports.useClientSideDefer = exports.RenderAfterCommit__DO_NOT_USE = exports.useRerenderOnChange = exports.useLazyReference = exports.useSubscribeToMultiple = exports.useReadAndSubscribe = exports.useResult = exports.FragmentReader = exports.useImperativeReference = exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.check = exports.registerLogger = exports.logMessage = exports.stableIdForFragmentReference = exports.readButDoNotEvaluate = exports.assertIsEntrypoint = exports.defaultMissingFieldHandler = exports.createIsographStore = exports.createIsographEnvironment = exports.ROOT_ID = exports.makeNetworkRequest = exports.normalizeData = exports.subscribe = exports.wrapPromise = exports.wrapResolvedValue = exports.getPromiseState = exports.readPromise = exports.garbageCollectEnvironment = exports.unretainQuery = exports.retainQuery = void 0;
3
+ exports.useImperativeLoadableField = exports.useConnectionSpecPagination = exports.useSkipLimitPagination = exports.useImperativeExposedMutationField = exports.useClientSideDefer = exports.RenderAfterCommit__DO_NOT_USE = exports.useRerenderOnChange = exports.useLazyReference = exports.useSubscribeToMultiple = exports.useReadAndSubscribe = exports.useResult = exports.FragmentReader = exports.useImperativeReference = exports.useIsographEnvironment = exports.IsographEnvironmentProvider = exports.check = exports.registerLogger = exports.logMessage = exports.stableIdForFragmentReference = exports.readButDoNotEvaluate = exports.assertIsEntrypoint = exports.createIsographStore = exports.createIsographEnvironment = exports.ROOT_ID = exports.makeNetworkRequest = exports.normalizeData = exports.subscribe = exports.wrapPromise = exports.wrapResolvedValue = exports.getPromiseState = exports.readPromise = exports.garbageCollectEnvironment = exports.unretainQuery = exports.retainQuery = void 0;
4
4
  var garbageCollection_1 = require("./core/garbageCollection");
5
5
  Object.defineProperty(exports, "retainQuery", { enumerable: true, get: function () { return garbageCollection_1.retainQuery; } });
6
6
  Object.defineProperty(exports, "unretainQuery", { enumerable: true, get: function () { return garbageCollection_1.unretainQuery; } });
@@ -19,7 +19,6 @@ var IsographEnvironment_1 = require("./core/IsographEnvironment");
19
19
  Object.defineProperty(exports, "ROOT_ID", { enumerable: true, get: function () { return IsographEnvironment_1.ROOT_ID; } });
20
20
  Object.defineProperty(exports, "createIsographEnvironment", { enumerable: true, get: function () { return IsographEnvironment_1.createIsographEnvironment; } });
21
21
  Object.defineProperty(exports, "createIsographStore", { enumerable: true, get: function () { return IsographEnvironment_1.createIsographStore; } });
22
- Object.defineProperty(exports, "defaultMissingFieldHandler", { enumerable: true, get: function () { return IsographEnvironment_1.defaultMissingFieldHandler; } });
23
22
  var entrypoint_1 = require("./core/entrypoint");
24
23
  Object.defineProperty(exports, "assertIsEntrypoint", { enumerable: true, get: function () { return entrypoint_1.assertIsEntrypoint; } });
25
24
  var read_1 = require("./core/read");
@@ -25,7 +25,7 @@ function useImperativeReference(entrypoint) {
25
25
  readerArtifact: entrypoint.readerWithRefetchQueries.readerArtifact,
26
26
  nestedRefetchQueries: entrypoint.readerWithRefetchQueries.nestedRefetchQueries,
27
27
  }),
28
- root: { __link: IsographEnvironment_1.ROOT_ID },
28
+ root: { __link: IsographEnvironment_1.ROOT_ID, __typename: entrypoint.concreteType },
29
29
  variables,
30
30
  networkRequest,
31
31
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-3a36e9fb",
3
+ "version": "0.0.0-main-beecd3bf",
4
4
  "description": "Use Isograph with React",
5
5
  "homepage": "https://isograph.dev",
6
6
  "main": "dist/index.js",
@@ -19,9 +19,9 @@
19
19
  "iso-watch": "../../target/debug/isograph_cli --config ./isograph.config.json --watch"
20
20
  },
21
21
  "dependencies": {
22
- "@isograph/disposable-types": "0.0.0-main-3a36e9fb",
23
- "@isograph/react-disposable-state": "0.0.0-main-3a36e9fb",
24
- "@isograph/reference-counted-pointer": "0.0.0-main-3a36e9fb"
22
+ "@isograph/disposable-types": "0.0.0-main-beecd3bf",
23
+ "@isograph/react-disposable-state": "0.0.0-main-beecd3bf",
24
+ "@isograph/reference-counted-pointer": "0.0.0-main-beecd3bf"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": "18.3.1"
package/schema.graphql CHANGED
@@ -2,6 +2,7 @@ type Query {
2
2
  me: Economist!
3
3
  you: Economist!
4
4
  node(id: ID!): Node
5
+ query: Query!
5
6
  }
6
7
 
7
8
  type Economist implements Node {
@@ -35,7 +35,7 @@ export type FragmentReference<
35
35
  export function stableIdForFragmentReference(
36
36
  fragmentReference: FragmentReference<any, any>,
37
37
  ): string {
38
- return `${fragmentReference.root.__link}/TODO_FRAGMENT_NAME/${serializeVariables(fragmentReference.variables ?? {})}`;
38
+ return `${fragmentReference.root.__typename}/${fragmentReference.root.__link}/TODO_FRAGMENT_NAME/${serializeVariables(fragmentReference.variables ?? {})}`;
39
39
  }
40
40
 
41
41
  function serializeVariables(variables: Variables) {
@@ -82,6 +82,7 @@ export type IsographNetworkFunction = (
82
82
 
83
83
  export type Link = {
84
84
  readonly __link: DataId;
85
+ readonly __typename: TypeName;
85
86
  };
86
87
 
87
88
  export type DataTypeValue =
@@ -111,8 +112,12 @@ export type DataId = string;
111
112
  export const ROOT_ID: DataId & '__ROOT' = '__ROOT';
112
113
 
113
114
  export type IsographStore = {
114
- [index: DataId]: StoreRecord | null;
115
- readonly __ROOT: StoreRecord;
115
+ [index: TypeName]: {
116
+ [index: DataId]: StoreRecord | null;
117
+ } | null;
118
+ readonly Query: {
119
+ readonly __ROOT: StoreRecord;
120
+ };
116
121
  };
117
122
 
118
123
  const DEFAULT_GC_BUFFER_SIZE = 10;
@@ -139,29 +144,12 @@ export function createIsographEnvironment(
139
144
 
140
145
  export function createIsographStore(): IsographStore {
141
146
  return {
142
- [ROOT_ID]: {},
147
+ Query: {
148
+ [ROOT_ID]: {},
149
+ },
143
150
  };
144
151
  }
145
152
 
146
- export function defaultMissingFieldHandler(
147
- _storeRecord: StoreRecord,
148
- _root: Link,
149
- fieldName: string,
150
- arguments_: { [index: string]: any } | null,
151
- variables: Variables | null,
152
- ): Link | undefined {
153
- if (fieldName === 'node' || fieldName === 'user') {
154
- const variable = arguments_?.['id'];
155
- const value = variables?.[variable];
156
-
157
- // TODO can we handle explicit nulls here too? Probably, after wrapping in objects
158
- if (value != null) {
159
- // @ts-expect-error
160
- return { __link: value };
161
- }
162
- }
163
- }
164
-
165
153
  export function assertLink(link: DataTypeValue): Link | null | undefined {
166
154
  if (Array.isArray(link)) {
167
155
  throw new Error('Unexpected array');
@@ -179,10 +167,12 @@ export function getLink(maybeLink: DataTypeValue): Link | null {
179
167
  if (
180
168
  maybeLink != null &&
181
169
  typeof maybeLink === 'object' &&
182
- // @ts-expect-error this is safe
183
- maybeLink.__link != null
170
+ '__link' in maybeLink &&
171
+ maybeLink.__link != null &&
172
+ '__typename' in maybeLink &&
173
+ maybeLink.__typename != null
184
174
  ) {
185
- return maybeLink as any;
175
+ return maybeLink;
186
176
  }
187
177
  return null;
188
178
  }
package/src/core/cache.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  DataTypeValue,
13
13
  getLink,
14
14
  FragmentSubscription,
15
+ type TypeName,
15
16
  } from './IsographEnvironment';
16
17
  import {
17
18
  IsographEntrypoint,
@@ -35,7 +36,7 @@ import { wrapResolvedValue } from './PromiseWrapper';
35
36
  import { logMessage } from './logging';
36
37
  import { DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from './check';
37
38
 
38
- const TYPENAME_FIELD_NAME = '__typename';
39
+ export const TYPENAME_FIELD_NAME = '__typename';
39
40
 
40
41
  export function getOrCreateItemInSuspenseCache<
41
42
  TReadFromStore extends { parameters: object; data: object },
@@ -113,7 +114,7 @@ export function getOrCreateCacheForArtifact<
113
114
  nestedRefetchQueries:
114
115
  entrypoint.readerWithRefetchQueries.nestedRefetchQueries,
115
116
  }),
116
- root: { __link: ROOT_ID },
117
+ root: { __link: ROOT_ID, __typename: entrypoint.concreteType },
117
118
  variables,
118
119
  networkRequest: networkRequest,
119
120
  },
@@ -137,6 +138,7 @@ export type NetworkResponseObject = {
137
138
  // undefined should not *actually* be present in the network response.
138
139
  [index: string]: undefined | NetworkResponseValue;
139
140
  id?: DataId;
141
+ __typename?: TypeName;
140
142
  };
141
143
 
142
144
  export function normalizeData(
@@ -145,8 +147,9 @@ export function normalizeData(
145
147
  networkResponse: NetworkResponseObject,
146
148
  variables: Variables,
147
149
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
148
- ): Set<DataId> {
149
- const encounteredIds = new Set<DataId>();
150
+ root: Link,
151
+ ): EncounteredIds {
152
+ const encounteredIds: EncounteredIds = new Map();
150
153
 
151
154
  logMessage(environment, {
152
155
  kind: 'AboutToNormalize',
@@ -154,13 +157,17 @@ export function normalizeData(
154
157
  networkResponse,
155
158
  variables,
156
159
  });
160
+
161
+ const recordsById = (environment.store[root.__typename] ??= {});
162
+ const newStoreRecord = (recordsById[root.__link] ??= {});
163
+
157
164
  normalizeDataIntoRecord(
158
165
  environment,
159
166
  normalizationAst,
160
167
  networkResponse,
161
- environment.store.__ROOT,
162
- { __link: ROOT_ID },
163
- variables as any,
168
+ newStoreRecord,
169
+ root,
170
+ variables,
164
171
  nestedRefetchQueries,
165
172
  encounteredIds,
166
173
  );
@@ -255,7 +262,7 @@ function withErrorHandling<T>(f: (t: T) => void): (t: T) => void {
255
262
 
256
263
  function callSubscriptions(
257
264
  environment: IsographEnvironment,
258
- recordsEncounteredWhenNormalizing: Set<DataId>,
265
+ recordsEncounteredWhenNormalizing: EncounteredIds,
259
266
  ) {
260
267
  environment.subscriptions.forEach(
261
268
  withErrorHandling((subscription) => {
@@ -318,9 +325,9 @@ function callSubscriptions(
318
325
  }
319
326
  case 'AnyChangesToRecord': {
320
327
  if (
321
- recordsEncounteredWhenNormalizing.has(
322
- subscription.recordLink.__link,
323
- )
328
+ recordsEncounteredWhenNormalizing
329
+ .get(subscription.recordLink.__typename)
330
+ ?.has(subscription.recordLink.__link)
324
331
  ) {
325
332
  subscription.callback();
326
333
  }
@@ -337,7 +344,25 @@ function callSubscriptions(
337
344
  );
338
345
  }
339
346
 
340
- function hasOverlappingIds(set1: Set<DataId>, set2: Set<DataId>): boolean {
347
+ function hasOverlappingIds(
348
+ ids1: EncounteredIds,
349
+ ids2: EncounteredIds,
350
+ ): boolean {
351
+ for (const [typeName, set1] of ids1.entries()) {
352
+ const set2 = ids2.get(typeName);
353
+ if (set2 === undefined) {
354
+ continue;
355
+ }
356
+
357
+ if (isNotDisjointFrom(set1, set2)) {
358
+ return true;
359
+ }
360
+ }
361
+ return false;
362
+ }
363
+
364
+ // TODO use a polyfill library
365
+ function isNotDisjointFrom<T>(set1: Set<T>, set2: Set<T>): boolean {
341
366
  for (const id of set1) {
342
367
  if (set2.has(id)) {
343
368
  return true;
@@ -346,6 +371,7 @@ function hasOverlappingIds(set1: Set<DataId>, set2: Set<DataId>): boolean {
346
371
  return false;
347
372
  }
348
373
 
374
+ export type EncounteredIds = Map<TypeName, Set<DataId>>;
349
375
  /**
350
376
  * Mutate targetParentRecord according to the normalizationAst and networkResponseParentRecord.
351
377
  */
@@ -357,7 +383,7 @@ function normalizeDataIntoRecord(
357
383
  targetParentRecordLink: Link,
358
384
  variables: Variables,
359
385
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
360
- mutableEncounteredIds: Set<DataId>,
386
+ mutableEncounteredIds: EncounteredIds,
361
387
  ): RecordHasBeenUpdated {
362
388
  let recordHasBeenUpdated = false;
363
389
  for (const normalizationNode of normalizationAst) {
@@ -412,11 +438,25 @@ function normalizeDataIntoRecord(
412
438
  }
413
439
  }
414
440
  if (recordHasBeenUpdated) {
415
- mutableEncounteredIds.add(targetParentRecordLink.__link);
441
+ let encounteredRecordsIds = insertIfNotExists(
442
+ mutableEncounteredIds,
443
+ targetParentRecordLink.__typename,
444
+ );
445
+
446
+ encounteredRecordsIds.add(targetParentRecordLink.__link);
416
447
  }
417
448
  return recordHasBeenUpdated;
418
449
  }
419
450
 
451
+ export function insertIfNotExists<K, V>(map: Map<K, Set<V>>, key: K) {
452
+ let result = map.get(key);
453
+ if (result === undefined) {
454
+ result = new Set();
455
+ map.set(key, result);
456
+ }
457
+ return result;
458
+ }
459
+
420
460
  type RecordHasBeenUpdated = boolean;
421
461
  function normalizeScalarField(
422
462
  astNode: NormalizationScalarField,
@@ -451,7 +491,7 @@ function normalizeLinkedField(
451
491
  targetParentRecordLink: Link,
452
492
  variables: Variables,
453
493
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
454
- mutableEncounteredIds: Set<DataId>,
494
+ mutableEncounteredIds: EncounteredIds,
455
495
  ): RecordHasBeenUpdated {
456
496
  const networkResponseKey = getNetworkResponseKey(astNode);
457
497
  const networkResponseData = networkResponseParentRecord[networkResponseKey];
@@ -492,7 +532,18 @@ function normalizeLinkedField(
492
532
  mutableEncounteredIds,
493
533
  );
494
534
 
495
- dataIds.push({ __link: newStoreRecordId });
535
+ const __typename =
536
+ astNode.concreteType ?? networkResponseObject[TYPENAME_FIELD_NAME];
537
+ if (__typename == null) {
538
+ throw new Error(
539
+ 'Unexpected missing __typename in network response when normalizing a linked field. ' +
540
+ 'This is indicative of a bug in Isograph.',
541
+ );
542
+ }
543
+ dataIds.push({
544
+ __link: newStoreRecordId,
545
+ __typename,
546
+ });
496
547
  }
497
548
  targetParentRecord[parentRecordKey] = dataIds;
498
549
  return !dataIdsAreTheSame(existingValue, dataIds);
@@ -508,11 +559,23 @@ function normalizeLinkedField(
508
559
  mutableEncounteredIds,
509
560
  );
510
561
 
562
+ let __typename =
563
+ astNode.concreteType ?? networkResponseData[TYPENAME_FIELD_NAME];
564
+
565
+ if (__typename == null) {
566
+ throw new Error(
567
+ 'Unexpected missing __typename in network response when normalizing a linked field. ' +
568
+ 'This is indicative of a bug in Isograph.',
569
+ );
570
+ }
571
+
511
572
  targetParentRecord[parentRecordKey] = {
512
573
  __link: newStoreRecordId,
574
+ __typename,
513
575
  };
576
+
514
577
  const link = getLink(existingValue);
515
- return link?.__link !== newStoreRecordId;
578
+ return link?.__link !== newStoreRecordId || link.__typename !== __typename;
516
579
  }
517
580
  }
518
581
 
@@ -527,7 +590,7 @@ function normalizeInlineFragment(
527
590
  targetParentRecordLink: Link,
528
591
  variables: Variables,
529
592
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
530
- mutableEncounteredIds: Set<DataId>,
593
+ mutableEncounteredIds: EncounteredIds,
531
594
  ): RecordHasBeenUpdated {
532
595
  const typeToRefineTo = astNode.type;
533
596
  if (networkResponseParentRecord[TYPENAME_FIELD_NAME] === typeToRefineTo) {
@@ -556,7 +619,10 @@ function dataIdsAreTheSame(
556
619
  }
557
620
  for (let i = 0; i < newDataIds.length; i++) {
558
621
  const maybeLink = getLink(existingValue[i]);
559
- if (newDataIds[i]?.__link !== maybeLink?.__link) {
622
+ if (
623
+ newDataIds[i]?.__link !== maybeLink?.__link ||
624
+ newDataIds[i]?.__typename !== maybeLink?.__typename
625
+ ) {
560
626
  return false;
561
627
  }
562
628
  }
@@ -574,7 +640,7 @@ function normalizeNetworkResponseObject(
574
640
  variables: Variables,
575
641
  index: number | null,
576
642
  nestedRefetchQueries: RefetchQueryNormalizationArtifactWrapper[],
577
- mutableEncounteredIds: Set<DataId>,
643
+ mutableEncounteredIds: EncounteredIds,
578
644
  ): DataId /* The id of the modified or newly created item */ {
579
645
  const newStoreRecordId = getDataIdOfNetworkResponse(
580
646
  targetParentRecordLink,
@@ -583,16 +649,25 @@ function normalizeNetworkResponseObject(
583
649
  variables,
584
650
  index,
585
651
  );
652
+ const __typename =
653
+ astNode.concreteType ?? networkResponseData[TYPENAME_FIELD_NAME];
586
654
 
587
- const newStoreRecord = environment.store[newStoreRecordId] ?? {};
588
- environment.store[newStoreRecordId] = newStoreRecord;
655
+ if (__typename == null) {
656
+ throw new Error(
657
+ 'Unexpected missing __typename in network response object. ' +
658
+ 'This is indicative of a bug in Isograph.',
659
+ );
660
+ }
661
+
662
+ const recordsById = (environment.store[__typename] ??= {});
663
+ const newStoreRecord = (recordsById[newStoreRecordId] ??= {});
589
664
 
590
665
  normalizeDataIntoRecord(
591
666
  environment,
592
667
  astNode.selections,
593
668
  networkResponseData,
594
669
  newStoreRecord,
595
- { __link: newStoreRecordId },
670
+ { __link: newStoreRecordId, __typename: __typename },
596
671
  variables,
597
672
  nestedRefetchQueries,
598
673
  mutableEncounteredIds,
@@ -726,10 +801,16 @@ export const SECOND_SPLIT_KEY = '___';
726
801
  function getDataIdOfNetworkResponse(
727
802
  parentRecordLink: Link,
728
803
  dataToNormalize: NetworkResponseObject,
729
- astNode: NormalizationLinkedField | NormalizationScalarField,
804
+ astNode: NormalizationLinkedField,
730
805
  variables: Variables,
731
806
  index: number | null,
732
807
  ): DataId {
808
+ // If we are dealing with nested Query, use __ROOT as id
809
+ // TODO do not hard code this value here
810
+ if (astNode.concreteType === 'Query') {
811
+ return ROOT_ID;
812
+ }
813
+
733
814
  // Check whether the dataToNormalize has an id field. If so, that is the key.
734
815
  // If not, we construct an id from the parentRecordId and the field parameters.
735
816
 
@@ -738,7 +819,7 @@ function getDataIdOfNetworkResponse(
738
819
  return dataId;
739
820
  }
740
821
 
741
- let storeKey = `${parentRecordLink.__link}.${astNode.fieldName}`;
822
+ let storeKey = `${parentRecordLink.__typename}:${parentRecordLink.__link}.${astNode.fieldName}`;
742
823
  if (index != null) {
743
824
  storeKey += `.${index}`;
744
825
  }
package/src/core/check.ts CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  getLink,
6
6
  IsographEnvironment,
7
7
  Link,
8
- ROOT_ID,
9
8
  StoreRecord,
10
9
  } from './IsographEnvironment';
11
10
  import { logMessage } from './logging';
@@ -31,13 +30,17 @@ export function check(
31
30
  environment: IsographEnvironment,
32
31
  normalizationAst: NormalizationAst,
33
32
  variables: Variables,
33
+ root: Link,
34
34
  ): CheckResult {
35
+ const recordsById = (environment.store[root.__typename] ??= {});
36
+ const newStoreRecord = (recordsById[root.__link] ??= {});
37
+
35
38
  const checkResult = checkFromRecord(
36
39
  environment,
37
40
  normalizationAst,
38
41
  variables,
39
- environment.store[ROOT_ID],
40
- { __link: ROOT_ID },
42
+ newStoreRecord,
43
+ root,
41
44
  );
42
45
  logMessage(environment, {
43
46
  kind: 'EnvironmentCheck',
@@ -97,7 +100,8 @@ function checkFromRecord(
97
100
  );
98
101
  }
99
102
 
100
- const linkedRecord = environment.store[link.__link];
103
+ const linkedRecord =
104
+ environment.store[link.__typename]?.[link.__link];
101
105
 
102
106
  if (linkedRecord === undefined) {
103
107
  return {
@@ -130,7 +134,8 @@ function checkFromRecord(
130
134
  );
131
135
  }
132
136
 
133
- const linkedRecord = environment.store[link.__link];
137
+ const linkedRecord =
138
+ environment.store[link.__typename]?.[link.__link];
134
139
 
135
140
  if (linkedRecord === undefined) {
136
141
  return {
@@ -32,6 +32,7 @@ export type IsographEntrypoint<
32
32
  TReadFromStore,
33
33
  TClientFieldValue
34
34
  >;
35
+ readonly concreteType: TypeName;
35
36
  };
36
37
 
37
38
  export type IsographEntrypointLoader<
@@ -75,6 +76,7 @@ export type NormalizationInlineFragment = {
75
76
  export type RefetchQueryNormalizationArtifact = {
76
77
  readonly kind: 'RefetchQuery';
77
78
  readonly networkRequestInfo: NetworkRequestInfo;
79
+ readonly concreteType: TypeName;
78
80
  };
79
81
 
80
82
  // TODO rename