@isograph/react 0.0.0-main-2a45cb8e → 0.0.0-main-cd6f81ae

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 (34) hide show
  1. package/dist/core/cache.d.ts +1 -1
  2. package/dist/core/cache.js +3 -3
  3. package/dist/core/check.d.ts +3 -3
  4. package/dist/core/check.js +10 -21
  5. package/dist/core/makeNetworkRequest.d.ts +2 -2
  6. package/dist/core/makeNetworkRequest.js +2 -2
  7. package/dist/core/read.js +8 -3
  8. package/dist/core/reader.d.ts +2 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/loadable-hooks/useClientSideDefer.d.ts +3 -2
  11. package/dist/loadable-hooks/useClientSideDefer.js +2 -2
  12. package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +2 -1
  13. package/dist/loadable-hooks/useConnectionSpecPagination.js +2 -2
  14. package/dist/loadable-hooks/useImperativeLoadableField.d.ts +2 -1
  15. package/dist/loadable-hooks/useImperativeLoadableField.js +2 -2
  16. package/dist/loadable-hooks/useSkipLimitPagination.d.ts +2 -1
  17. package/dist/loadable-hooks/useSkipLimitPagination.js +2 -2
  18. package/dist/react/useImperativeReference.d.ts +1 -1
  19. package/dist/react/useImperativeReference.js +3 -3
  20. package/dist/react/useLazyReference.d.ts +1 -1
  21. package/dist/react/useLazyReference.js +2 -2
  22. package/package.json +4 -4
  23. package/src/core/cache.ts +4 -4
  24. package/src/core/check.ts +11 -19
  25. package/src/core/makeNetworkRequest.ts +3 -3
  26. package/src/core/read.ts +16 -4
  27. package/src/core/reader.ts +6 -0
  28. package/src/index.ts +1 -1
  29. package/src/loadable-hooks/useClientSideDefer.ts +5 -1
  30. package/src/loadable-hooks/useConnectionSpecPagination.ts +10 -6
  31. package/src/loadable-hooks/useImperativeLoadableField.ts +6 -1
  32. package/src/loadable-hooks/useSkipLimitPagination.ts +10 -6
  33. package/src/react/useImperativeReference.ts +6 -5
  34. package/src/react/useLazyReference.ts +2 -2
@@ -18,7 +18,7 @@ export declare function stableCopy<T>(value: T): T;
18
18
  export declare function getOrCreateCacheForArtifact<TReadFromStore extends {
19
19
  parameters: object;
20
20
  data: object;
21
- }, TClientFieldValue>(environment: IsographEnvironment, entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: ExtractParameters<TReadFromStore>, options?: FetchOptions): ParentCache<FragmentReference<TReadFromStore, TClientFieldValue>>;
21
+ }, TClientFieldValue>(environment: IsographEnvironment, entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: ExtractParameters<TReadFromStore>, fetchOptions?: FetchOptions): ParentCache<FragmentReference<TReadFromStore, TClientFieldValue>>;
22
22
  type NetworkResponseScalarValue = string | number | boolean;
23
23
  type NetworkResponseValue = NetworkResponseScalarValue | null | NetworkResponseObject | NetworkResponseObject[] | NetworkResponseScalarValue[];
24
24
  export type NetworkResponseObject = {
@@ -53,12 +53,12 @@ function stableCopy(value) {
53
53
  }
54
54
  return stable;
55
55
  }
56
- function getOrCreateCacheForArtifact(environment, entrypoint, variables, options) {
56
+ function getOrCreateCacheForArtifact(environment, entrypoint, variables, fetchOptions) {
57
57
  const cacheKey = entrypoint.queryText + JSON.stringify(stableCopy(variables));
58
58
  const factory = () => {
59
59
  var _a;
60
- const fetchPolicy = (_a = options === null || options === void 0 ? void 0 : options.fetchPolicy) !== null && _a !== void 0 ? _a : check_1.DEFAULT_FETCH_POLICY;
61
- const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, variables, fetchPolicy);
60
+ const shouldFetch = (_a = fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.shouldFetch) !== null && _a !== void 0 ? _a : check_1.DEFAULT_SHOULD_FETCH_VALUE;
61
+ const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, variables, shouldFetch);
62
62
  const itemCleanupPair = [
63
63
  {
64
64
  kind: 'FragmentReference',
@@ -1,10 +1,10 @@
1
1
  import { NormalizationAst } from './entrypoint';
2
2
  import { Variables } from './FragmentReference';
3
3
  import { IsographEnvironment, Link } from './IsographEnvironment';
4
- export type FetchPolicy = 'Yes' | 'No' | 'IfNecessary';
5
- export declare const DEFAULT_FETCH_POLICY: FetchPolicy;
4
+ export type ShouldFetch = 'Yes' | 'No' | 'IfNecessary';
5
+ export declare const DEFAULT_SHOULD_FETCH_VALUE: ShouldFetch;
6
6
  export type FetchOptions = {
7
- fetchPolicy?: FetchPolicy;
7
+ shouldFetch?: ShouldFetch;
8
8
  };
9
9
  export type CheckResult = {
10
10
  kind: 'EnoughData';
@@ -1,21 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_FETCH_POLICY = void 0;
3
+ exports.DEFAULT_SHOULD_FETCH_VALUE = void 0;
4
4
  exports.check = check;
5
5
  const cache_1 = require("./cache");
6
6
  const IsographEnvironment_1 = require("./IsographEnvironment");
7
7
  const logging_1 = require("./logging");
8
- exports.DEFAULT_FETCH_POLICY = 'IfNecessary';
8
+ exports.DEFAULT_SHOULD_FETCH_VALUE = 'IfNecessary';
9
9
  function check(environment, normalizationAst, variables) {
10
- const checkResult = checkFromRecord(environment, normalizationAst, variables, environment.store[IsographEnvironment_1.ROOT_ID], IsographEnvironment_1.ROOT_ID);
10
+ const checkResult = checkFromRecord(environment, normalizationAst, variables, environment.store[IsographEnvironment_1.ROOT_ID], { __link: IsographEnvironment_1.ROOT_ID });
11
11
  (0, logging_1.logMessage)(environment, {
12
12
  kind: 'EnvironmentCheck',
13
13
  result: checkResult,
14
14
  });
15
15
  return checkResult;
16
16
  }
17
- function checkFromRecord(environment, normalizationAst, variables, record, backupId) {
18
- var _a, _b, _c;
17
+ function checkFromRecord(environment, normalizationAst, variables, record, recordLink) {
19
18
  normalizationAstLoop: for (const normalizationAstNode of normalizationAst) {
20
19
  switch (normalizationAstNode.kind) {
21
20
  case 'Scalar': {
@@ -26,9 +25,7 @@ function checkFromRecord(environment, normalizationAst, variables, record, backu
26
25
  if (scalarValue === undefined) {
27
26
  return {
28
27
  kind: 'MissingData',
29
- record: {
30
- __link: (_a = record.id) !== null && _a !== void 0 ? _a : backupId,
31
- },
28
+ record: recordLink,
32
29
  };
33
30
  }
34
31
  continue normalizationAstLoop;
@@ -39,9 +36,7 @@ function checkFromRecord(environment, normalizationAst, variables, record, backu
39
36
  if (linkedValue === undefined) {
40
37
  return {
41
38
  kind: 'MissingData',
42
- record: {
43
- __link: (_b = record.id) !== null && _b !== void 0 ? _b : backupId,
44
- },
39
+ record: recordLink,
45
40
  };
46
41
  }
47
42
  else if (linkedValue === null) {
@@ -66,9 +61,7 @@ function checkFromRecord(environment, normalizationAst, variables, record, backu
66
61
  }
67
62
  else {
68
63
  // TODO in __DEV__ assert linkedRecord is an object
69
- const result = checkFromRecord(environment, normalizationAstNode.selections, variables, linkedRecord,
70
- // TODO this seems likely to be wrong
71
- backupId + '.' + parentRecordKey);
64
+ const result = checkFromRecord(environment, normalizationAstNode.selections, variables, linkedRecord, link);
72
65
  if (result.kind === 'MissingData') {
73
66
  return result;
74
67
  }
@@ -93,9 +86,7 @@ function checkFromRecord(environment, normalizationAst, variables, record, backu
93
86
  }
94
87
  else {
95
88
  // TODO in __DEV__ assert linkedRecord is an object
96
- const result = checkFromRecord(environment, normalizationAstNode.selections, variables, linkedRecord,
97
- // TODO this seems likely to be wrong
98
- backupId + '.' + parentRecordKey);
89
+ const result = checkFromRecord(environment, normalizationAstNode.selections, variables, linkedRecord, link);
99
90
  if (result.kind === 'MissingData') {
100
91
  return result;
101
92
  }
@@ -109,12 +100,10 @@ function checkFromRecord(environment, normalizationAst, variables, record, backu
109
100
  existingRecordTypename !== normalizationAstNode.type) {
110
101
  return {
111
102
  kind: 'MissingData',
112
- record: {
113
- __link: (_c = record.id) !== null && _c !== void 0 ? _c : backupId,
114
- },
103
+ record: recordLink,
115
104
  };
116
105
  }
117
- const result = checkFromRecord(environment, normalizationAstNode.selections, variables, record, backupId);
106
+ const result = checkFromRecord(environment, normalizationAstNode.selections, variables, record, recordLink);
118
107
  if (result.kind === 'MissingData') {
119
108
  return result;
120
109
  }
@@ -3,6 +3,6 @@ import { IsographEntrypoint, RefetchQueryNormalizationArtifact } from './entrypo
3
3
  import { Variables } from './FragmentReference';
4
4
  import { IsographEnvironment } from './IsographEnvironment';
5
5
  import { AnyError, PromiseWrapper } from './PromiseWrapper';
6
- import { FetchPolicy } from './check';
7
- export declare function maybeMakeNetworkRequest(environment: IsographEnvironment, artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>, variables: Variables, fetchPolicy: FetchPolicy): ItemCleanupPair<PromiseWrapper<void, AnyError>>;
6
+ import { ShouldFetch } from './check';
7
+ export declare function maybeMakeNetworkRequest(environment: IsographEnvironment, artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>, variables: Variables, shouldFetch: ShouldFetch): ItemCleanupPair<PromiseWrapper<void, AnyError>>;
8
8
  export declare function makeNetworkRequest(environment: IsographEnvironment, artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>, variables: Variables): ItemCleanupPair<PromiseWrapper<void, AnyError>>;
@@ -8,8 +8,8 @@ const cache_1 = require("./cache");
8
8
  const logging_1 = require("./logging");
9
9
  const check_1 = require("./check");
10
10
  let networkRequestId = 0;
11
- function maybeMakeNetworkRequest(environment, artifact, variables, fetchPolicy) {
12
- switch (fetchPolicy) {
11
+ function maybeMakeNetworkRequest(environment, artifact, variables, shouldFetch) {
12
+ switch (shouldFetch) {
13
13
  case 'Yes': {
14
14
  return makeNetworkRequest(environment, artifact, variables);
15
15
  }
package/dist/core/read.js CHANGED
@@ -8,6 +8,7 @@ const IsographEnvironment_1 = require("./IsographEnvironment");
8
8
  const makeNetworkRequest_1 = require("./makeNetworkRequest");
9
9
  const PromiseWrapper_1 = require("./PromiseWrapper");
10
10
  const logging_1 = require("./logging");
11
+ const check_1 = require("./check");
11
12
  function readButDoNotEvaluate(environment, fragmentReference, networkRequestOptions) {
12
13
  var _a;
13
14
  const mutableEncounteredRecords = new Set();
@@ -265,7 +266,7 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
265
266
  };
266
267
  }
267
268
  else {
268
- target[field.alias] = (args) => {
269
+ target[field.alias] = (args, fetchOptions) => {
269
270
  // TODO we should use the reader AST for this
270
271
  const includeReadOutData = (variables, readOutData) => {
271
272
  variables.id = readOutData.id;
@@ -283,7 +284,9 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
283
284
  // Fetcher
284
285
  () => {
285
286
  const fragmentReferenceAndDisposeFromEntrypoint = (entrypoint) => {
286
- const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.makeNetworkRequest)(environment, entrypoint, localVariables);
287
+ var _a;
288
+ const shouldFetch = (_a = fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.shouldFetch) !== null && _a !== void 0 ? _a : check_1.DEFAULT_SHOULD_FETCH_VALUE;
289
+ const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, localVariables, shouldFetch);
287
290
  const fragmentReference = {
288
291
  kind: 'FragmentReference',
289
292
  readerWithRefetchQueries: (0, PromiseWrapper_1.wrapResolvedValue)({
@@ -312,8 +315,10 @@ function readData(environment, ast, root, variables, nestedRefetchQueries, netwo
312
315
  // Promise is pending or thrown
313
316
  let entrypointLoaderState = { kind: 'EntrypointNotLoaded' };
314
317
  const networkRequest = (0, PromiseWrapper_1.wrapPromise)(isographArtifactPromiseWrapper.promise.then((entrypoint) => {
318
+ var _a;
315
319
  if (entrypointLoaderState.kind === 'EntrypointNotLoaded') {
316
- const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.makeNetworkRequest)(environment, entrypoint, localVariables);
320
+ const shouldFetch = (_a = fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.shouldFetch) !== null && _a !== void 0 ? _a : check_1.DEFAULT_SHOULD_FETCH_VALUE;
321
+ const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, localVariables, shouldFetch);
317
322
  entrypointLoaderState = {
318
323
  kind: 'NetworkRequestStarted',
319
324
  disposeNetworkRequest,
@@ -3,6 +3,7 @@ import { FragmentReference, ExtractParameters, ExtractData } from './FragmentRef
3
3
  import { ComponentOrFieldName, IsographEnvironment, type Link } from './IsographEnvironment';
4
4
  import { IsographEntrypoint, IsographEntrypointLoader, RefetchQueryNormalizationArtifact, RefetchQueryNormalizationArtifactWrapper } from './entrypoint';
5
5
  import { Arguments } from './util';
6
+ import { FetchOptions } from './check';
6
7
  export type TopLevelReaderArtifact<TReadFromStore extends {
7
8
  parameters: object;
8
9
  data: object;
@@ -77,5 +78,5 @@ type StableId = string;
77
78
  export type LoadableField<TReadFromStore extends {
78
79
  data: object;
79
80
  parameters: object;
80
- }, TResult, TArgs = ExtractParameters<TReadFromStore>> = (args: TArgs | void) => [StableId, Factory<FragmentReference<TReadFromStore, TResult>>];
81
+ }, TResult, TArgs = ExtractParameters<TReadFromStore>> = (args: TArgs | void, fetchOptions: FetchOptions) => [StableId, Factory<FragmentReference<TReadFromStore, TResult>>];
81
82
  export {};
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export { readButDoNotEvaluate } from './core/read';
9
9
  export { type ExtractSecondParam, type CombineWithIntrinsicAttributes, type Argument, type ArgumentName, type ArgumentValue, type Arguments, } from './core/util';
10
10
  export { type FragmentReference, type Variables, type ExtractParameters, type ExtractData, stableIdForFragmentReference, } from './core/FragmentReference';
11
11
  export { type LogMessage, type LogFunction, logMessage, registerLogger, } from './core/logging';
12
- export { check, CheckResult, FetchOptions, FetchPolicy } from './core/check';
12
+ export { check, CheckResult, FetchOptions, ShouldFetch } from './core/check';
13
13
  export { IsographEnvironmentProvider, useIsographEnvironment, type IsographEnvironmentProviderProps, } from './react/IsographEnvironmentProvider';
14
14
  export { useImperativeReference } from './react/useImperativeReference';
15
15
  export { FragmentReader } from './react/FragmentReader';
@@ -1,14 +1,15 @@
1
1
  import { ExtractParameters, FragmentReference } from '../core/FragmentReference';
2
2
  import { LoadableField } from '../core/reader';
3
+ import { FetchOptions } from '../core/check';
3
4
  export declare function useClientSideDefer<TReadFromStore extends {
4
5
  data: object;
5
6
  parameters: object;
6
- }, TResult>(loadableField: LoadableField<TReadFromStore, TResult, ExtractParameters<TReadFromStore>>): {
7
+ }, TResult>(loadableField: LoadableField<TReadFromStore, TResult, ExtractParameters<TReadFromStore>>, fetchOptions?: FetchOptions): {
7
8
  fragmentReference: FragmentReference<TReadFromStore, TResult>;
8
9
  };
9
10
  export declare function useClientSideDefer<TReadFromStore extends {
10
11
  data: object;
11
12
  parameters: object;
12
- }, TResult, TProvidedArgs extends object>(loadableField: LoadableField<TReadFromStore, TResult, Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>>, args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>): {
13
+ }, TResult, TProvidedArgs extends object>(loadableField: LoadableField<TReadFromStore, TResult, Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>>, args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>, fetchOptions?: FetchOptions): {
13
14
  fragmentReference: FragmentReference<TReadFromStore, TResult>;
14
15
  };
@@ -4,8 +4,8 @@ exports.useClientSideDefer = useClientSideDefer;
4
4
  const IsographEnvironmentProvider_1 = require("../react/IsographEnvironmentProvider");
5
5
  const cache_1 = require("../core/cache");
6
6
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
7
- function useClientSideDefer(loadableField, args) {
8
- const [id, loader] = loadableField(args);
7
+ function useClientSideDefer(loadableField, args, fetchOptions) {
8
+ const [id, loader] = loadableField(args, fetchOptions !== null && fetchOptions !== void 0 ? fetchOptions : {});
9
9
  const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
10
10
  const cache = (0, cache_1.getOrCreateItemInSuspenseCache)(environment, id, loader);
11
11
  const fragmentReference = (0, react_disposable_state_1.useLazyDisposableState)(cache).state;
@@ -1,5 +1,6 @@
1
1
  import { FragmentReference } from '../core/FragmentReference';
2
2
  import { LoadableField } from '../core/reader';
3
+ import { FetchOptions } from '../core/check';
3
4
  type UsePaginationReturnValue<TReadFromStore extends {
4
5
  parameters: object;
5
6
  data: object;
@@ -9,7 +10,7 @@ type UsePaginationReturnValue<TReadFromStore extends {
9
10
  results: ReadonlyArray<TItem>;
10
11
  } | {
11
12
  kind: 'Complete';
12
- fetchMore: (count: number) => void;
13
+ fetchMore: (count: number, fetchOptions?: FetchOptions) => void;
13
14
  results: ReadonlyArray<TItem>;
14
15
  hasNextPage: boolean;
15
16
  };
@@ -65,11 +65,11 @@ function useConnectionSpecPagination(loadableField, pageInfo) {
65
65
  };
66
66
  });
67
67
  }
68
- const getFetchMore = (after) => (count) => {
68
+ const getFetchMore = (after) => (count, fetchOptions) => {
69
69
  const loadedField = loadableField({
70
70
  after: after,
71
71
  first: count,
72
- })[1]();
72
+ }, fetchOptions !== null && fetchOptions !== void 0 ? fetchOptions : {})[1]();
73
73
  const newPointer = (0, reference_counted_pointer_1.createReferenceCountedPointer)(loadedField);
74
74
  const clonedPointers = loadedReferences.map(([refCountedPointer]) => {
75
75
  const clonedRefCountedPointer = refCountedPointer.cloneIfNotDisposed();
@@ -1,12 +1,13 @@
1
1
  import { ExtractParameters, FragmentReference } from '../core/FragmentReference';
2
2
  import { UnassignedState } from '@isograph/react-disposable-state';
3
3
  import { LoadableField } from '../core/reader';
4
+ import { FetchOptions } from '../core/check';
4
5
  type UseImperativeLoadableFieldReturn<TReadFromStore extends {
5
6
  data: object;
6
7
  parameters: object;
7
8
  }, TResult, TProvidedArgs extends object> = {
8
9
  fragmentReference: FragmentReference<TReadFromStore, TResult> | UnassignedState;
9
- loadField: (args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs> | void) => void;
10
+ loadField: (args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs> | void, fetchOptions?: FetchOptions) => void;
10
11
  };
11
12
  export declare function useImperativeLoadableField<TReadFromStore extends {
12
13
  data: object;
@@ -5,8 +5,8 @@ const react_disposable_state_1 = require("@isograph/react-disposable-state");
5
5
  function useImperativeLoadableField(loadableField) {
6
6
  const { state, setState } = (0, react_disposable_state_1.useUpdatableDisposableState)();
7
7
  return {
8
- loadField: (args) => {
9
- const [_id, loader] = loadableField(args);
8
+ loadField: (args, fetchOptions) => {
9
+ const [_id, loader] = loadableField(args, fetchOptions !== null && fetchOptions !== void 0 ? fetchOptions : {});
10
10
  setState(loader());
11
11
  },
12
12
  fragmentReference: state,
@@ -1,11 +1,12 @@
1
1
  import { LoadableField } from '../core/reader';
2
2
  import { FragmentReference } from '../core/FragmentReference';
3
+ import { FetchOptions } from '../core/check';
3
4
  type UseSkipLimitReturnValue<TReadFromStore extends {
4
5
  data: object;
5
6
  parameters: object;
6
7
  }, TItem> = {
7
8
  readonly kind: 'Complete';
8
- readonly fetchMore: (count: number) => void;
9
+ readonly fetchMore: (count: number, fetchOptions?: FetchOptions) => void;
9
10
  readonly results: ReadonlyArray<TItem>;
10
11
  } | {
11
12
  readonly kind: 'Pending';
@@ -58,11 +58,11 @@ function useSkipLimitPagination(loadableField, initialArgs) {
58
58
  };
59
59
  });
60
60
  }
61
- const getFetchMore = (loadedSoFar) => (count) => {
61
+ const getFetchMore = (loadedSoFar) => (count, fetchOptions) => {
62
62
  const loadedField = loadableField({
63
63
  skip: loadedSoFar,
64
64
  limit: count,
65
- })[1]();
65
+ }, fetchOptions !== null && fetchOptions !== void 0 ? fetchOptions : {})[1]();
66
66
  const newPointer = (0, reference_counted_pointer_1.createReferenceCountedPointer)(loadedField);
67
67
  const clonedPointers = loadedReferences.map(([refCountedPointer]) => {
68
68
  const clonedRefCountedPointer = refCountedPointer.cloneIfNotDisposed();
@@ -7,5 +7,5 @@ export declare function useImperativeReference<TReadFromStore extends {
7
7
  data: object;
8
8
  }, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>): {
9
9
  fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue> | UnassignedState;
10
- loadFragmentReference: (variables: ExtractParameters<TReadFromStore>, options?: FetchOptions) => void;
10
+ loadFragmentReference: (variables: ExtractParameters<TReadFromStore>, fetchOptions?: FetchOptions) => void;
11
11
  };
@@ -13,10 +13,10 @@ function useImperativeReference(entrypoint) {
13
13
  const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
14
14
  return {
15
15
  fragmentReference: state,
16
- loadFragmentReference: (variables, options) => {
16
+ loadFragmentReference: (variables, fetchOptions) => {
17
17
  var _a;
18
- const fetchPolicy = (_a = options === null || options === void 0 ? void 0 : options.fetchPolicy) !== null && _a !== void 0 ? _a : check_1.DEFAULT_FETCH_POLICY;
19
- const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, variables, fetchPolicy);
18
+ const shouldFetch = (_a = fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.shouldFetch) !== null && _a !== void 0 ? _a : check_1.DEFAULT_SHOULD_FETCH_VALUE;
19
+ const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, variables, shouldFetch);
20
20
  setState([
21
21
  {
22
22
  kind: 'FragmentReference',
@@ -4,6 +4,6 @@ import { FetchOptions } from '../core/check';
4
4
  export declare function useLazyReference<TReadFromStore extends {
5
5
  parameters: object;
6
6
  data: object;
7
- }, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: ExtractParameters<TReadFromStore>, options?: FetchOptions): {
7
+ }, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: ExtractParameters<TReadFromStore>, fetchOptions?: FetchOptions): {
8
8
  fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>;
9
9
  };
@@ -5,7 +5,7 @@ const IsographEnvironmentProvider_1 = require("./IsographEnvironmentProvider");
5
5
  const cache_1 = require("../core/cache");
6
6
  const react_disposable_state_1 = require("@isograph/react-disposable-state");
7
7
  const logging_1 = require("../core/logging");
8
- function useLazyReference(entrypoint, variables, options) {
8
+ function useLazyReference(entrypoint, variables, fetchOptions) {
9
9
  const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
10
10
  if ((entrypoint === null || entrypoint === void 0 ? void 0 : entrypoint.kind) !== 'Entrypoint') {
11
11
  // TODO have a separate error logger
@@ -14,7 +14,7 @@ function useLazyReference(entrypoint, variables, options) {
14
14
  entrypoint,
15
15
  });
16
16
  }
17
- const cache = (0, cache_1.getOrCreateCacheForArtifact)(environment, entrypoint, variables, options);
17
+ const cache = (0, cache_1.getOrCreateCacheForArtifact)(environment, entrypoint, variables, fetchOptions);
18
18
  return {
19
19
  fragmentReference: (0, react_disposable_state_1.useLazyDisposableState)(cache).state,
20
20
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isograph/react",
3
- "version": "0.0.0-main-2a45cb8e",
3
+ "version": "0.0.0-main-cd6f81ae",
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-2a45cb8e",
23
- "@isograph/react-disposable-state": "0.0.0-main-2a45cb8e",
24
- "@isograph/reference-counted-pointer": "0.0.0-main-2a45cb8e"
22
+ "@isograph/disposable-types": "0.0.0-main-cd6f81ae",
23
+ "@isograph/react-disposable-state": "0.0.0-main-cd6f81ae",
24
+ "@isograph/reference-counted-pointer": "0.0.0-main-cd6f81ae"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": "18.3.1"
package/src/core/cache.ts CHANGED
@@ -33,7 +33,7 @@ import { mergeObjectsUsingReaderAst } from './areEqualWithDeepComparison';
33
33
  import { maybeMakeNetworkRequest } from './makeNetworkRequest';
34
34
  import { wrapResolvedValue } from './PromiseWrapper';
35
35
  import { logMessage } from './logging';
36
- import { DEFAULT_FETCH_POLICY, FetchOptions } from './check';
36
+ import { DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from './check';
37
37
 
38
38
  const TYPENAME_FIELD_NAME = '__typename';
39
39
 
@@ -88,16 +88,16 @@ export function getOrCreateCacheForArtifact<
88
88
  environment: IsographEnvironment,
89
89
  entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>,
90
90
  variables: ExtractParameters<TReadFromStore>,
91
- options?: FetchOptions,
91
+ fetchOptions?: FetchOptions,
92
92
  ): ParentCache<FragmentReference<TReadFromStore, TClientFieldValue>> {
93
93
  const cacheKey = entrypoint.queryText + JSON.stringify(stableCopy(variables));
94
94
  const factory = () => {
95
- const fetchPolicy = options?.fetchPolicy ?? DEFAULT_FETCH_POLICY;
95
+ const shouldFetch = fetchOptions?.shouldFetch ?? DEFAULT_SHOULD_FETCH_VALUE;
96
96
  const [networkRequest, disposeNetworkRequest] = maybeMakeNetworkRequest(
97
97
  environment,
98
98
  entrypoint,
99
99
  variables,
100
- fetchPolicy,
100
+ shouldFetch,
101
101
  );
102
102
 
103
103
  const itemCleanupPair: ItemCleanupPair<
package/src/core/check.ts CHANGED
@@ -10,12 +10,12 @@ import {
10
10
  } from './IsographEnvironment';
11
11
  import { logMessage } from './logging';
12
12
 
13
- export type FetchPolicy = 'Yes' | 'No' | 'IfNecessary';
13
+ export type ShouldFetch = 'Yes' | 'No' | 'IfNecessary';
14
14
 
15
- export const DEFAULT_FETCH_POLICY: FetchPolicy = 'IfNecessary';
15
+ export const DEFAULT_SHOULD_FETCH_VALUE: ShouldFetch = 'IfNecessary';
16
16
 
17
17
  export type FetchOptions = {
18
- fetchPolicy?: FetchPolicy;
18
+ shouldFetch?: ShouldFetch;
19
19
  };
20
20
 
21
21
  export type CheckResult =
@@ -37,7 +37,7 @@ export function check(
37
37
  normalizationAst,
38
38
  variables,
39
39
  environment.store[ROOT_ID],
40
- ROOT_ID,
40
+ { __link: ROOT_ID },
41
41
  );
42
42
  logMessage(environment, {
43
43
  kind: 'EnvironmentCheck',
@@ -51,7 +51,7 @@ function checkFromRecord(
51
51
  normalizationAst: NormalizationAst,
52
52
  variables: Variables,
53
53
  record: StoreRecord,
54
- backupId: string,
54
+ recordLink: Link,
55
55
  ): CheckResult {
56
56
  normalizationAstLoop: for (const normalizationAstNode of normalizationAst) {
57
57
  switch (normalizationAstNode.kind) {
@@ -67,9 +67,7 @@ function checkFromRecord(
67
67
  if (scalarValue === undefined) {
68
68
  return {
69
69
  kind: 'MissingData',
70
- record: {
71
- __link: record.id ?? backupId,
72
- },
70
+ record: recordLink,
73
71
  };
74
72
  }
75
73
  continue normalizationAstLoop;
@@ -85,9 +83,7 @@ function checkFromRecord(
85
83
  if (linkedValue === undefined) {
86
84
  return {
87
85
  kind: 'MissingData',
88
- record: {
89
- __link: record.id ?? backupId,
90
- },
86
+ record: recordLink,
91
87
  };
92
88
  } else if (linkedValue === null) {
93
89
  continue;
@@ -117,8 +113,7 @@ function checkFromRecord(
117
113
  normalizationAstNode.selections,
118
114
  variables,
119
115
  linkedRecord,
120
- // TODO this seems likely to be wrong
121
- backupId + '.' + parentRecordKey,
116
+ link,
122
117
  );
123
118
 
124
119
  if (result.kind === 'MissingData') {
@@ -151,8 +146,7 @@ function checkFromRecord(
151
146
  normalizationAstNode.selections,
152
147
  variables,
153
148
  linkedRecord,
154
- // TODO this seems likely to be wrong
155
- backupId + '.' + parentRecordKey,
149
+ link,
156
150
  );
157
151
 
158
152
  if (result.kind === 'MissingData') {
@@ -172,9 +166,7 @@ function checkFromRecord(
172
166
  ) {
173
167
  return {
174
168
  kind: 'MissingData',
175
- record: {
176
- __link: record.id ?? backupId,
177
- },
169
+ record: recordLink,
178
170
  };
179
171
  }
180
172
 
@@ -183,7 +175,7 @@ function checkFromRecord(
183
175
  normalizationAstNode.selections,
184
176
  variables,
185
177
  record,
186
- backupId,
178
+ recordLink,
187
179
  );
188
180
 
189
181
  if (result.kind === 'MissingData') {
@@ -19,7 +19,7 @@ import {
19
19
  } from './PromiseWrapper';
20
20
  import { normalizeData } from './cache';
21
21
  import { logMessage } from './logging';
22
- import { check, FetchPolicy } from './check';
22
+ import { check, ShouldFetch } from './check';
23
23
 
24
24
  let networkRequestId = 0;
25
25
 
@@ -27,9 +27,9 @@ export function maybeMakeNetworkRequest(
27
27
  environment: IsographEnvironment,
28
28
  artifact: RefetchQueryNormalizationArtifact | IsographEntrypoint<any, any>,
29
29
  variables: Variables,
30
- fetchPolicy: FetchPolicy,
30
+ shouldFetch: ShouldFetch,
31
31
  ): ItemCleanupPair<PromiseWrapper<void, AnyError>> {
32
- switch (fetchPolicy) {
32
+ switch (shouldFetch) {
33
33
  case 'Yes': {
34
34
  return makeNetworkRequest(environment, artifact, variables);
35
35
  }
package/src/core/read.ts CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  IsographEnvironment,
19
19
  type Link,
20
20
  } from './IsographEnvironment';
21
- import { makeNetworkRequest } from './makeNetworkRequest';
21
+ import { maybeMakeNetworkRequest } from './makeNetworkRequest';
22
22
  import {
23
23
  getPromiseState,
24
24
  PromiseWrapper,
@@ -30,6 +30,7 @@ import { ReaderAst } from './reader';
30
30
  import { Arguments } from './util';
31
31
  import { logMessage } from './logging';
32
32
  import { CleanupFn } from '@isograph/disposable-types';
33
+ import { DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from './check';
33
34
 
34
35
  export type WithEncounteredRecords<T> = {
35
36
  readonly encounteredRecords: Set<DataId>;
@@ -408,7 +409,7 @@ function readData<TReadFromStore>(
408
409
  recordLink: refetchReaderParams.recordLink,
409
410
  };
410
411
  } else {
411
- target[field.alias] = (args: any) => {
412
+ target[field.alias] = (args: any, fetchOptions?: FetchOptions) => {
412
413
  // TODO we should use the reader AST for this
413
414
  const includeReadOutData = (variables: any, readOutData: any) => {
414
415
  variables.id = readOutData.id;
@@ -436,8 +437,15 @@ function readData<TReadFromStore>(
436
437
  const fragmentReferenceAndDisposeFromEntrypoint = (
437
438
  entrypoint: IsographEntrypoint<any, any>,
438
439
  ): [FragmentReference<any, any>, CleanupFn] => {
440
+ const shouldFetch =
441
+ fetchOptions?.shouldFetch ?? DEFAULT_SHOULD_FETCH_VALUE;
439
442
  const [networkRequest, disposeNetworkRequest] =
440
- makeNetworkRequest(environment, entrypoint, localVariables);
443
+ maybeMakeNetworkRequest(
444
+ environment,
445
+ entrypoint,
446
+ localVariables,
447
+ shouldFetch,
448
+ );
441
449
 
442
450
  const fragmentReference: FragmentReference<any, any> = {
443
451
  kind: 'FragmentReference',
@@ -493,11 +501,15 @@ function readData<TReadFromStore>(
493
501
  if (
494
502
  entrypointLoaderState.kind === 'EntrypointNotLoaded'
495
503
  ) {
504
+ const shouldFetch =
505
+ fetchOptions?.shouldFetch ??
506
+ DEFAULT_SHOULD_FETCH_VALUE;
496
507
  const [networkRequest, disposeNetworkRequest] =
497
- makeNetworkRequest(
508
+ maybeMakeNetworkRequest(
498
509
  environment,
499
510
  entrypoint,
500
511
  localVariables,
512
+ shouldFetch,
501
513
  );
502
514
  entrypointLoaderState = {
503
515
  kind: 'NetworkRequestStarted',
@@ -16,6 +16,7 @@ import {
16
16
  RefetchQueryNormalizationArtifactWrapper,
17
17
  } from './entrypoint';
18
18
  import { Arguments } from './util';
19
+ import { FetchOptions } from './check';
19
20
 
20
21
  export type TopLevelReaderArtifact<
21
22
  TReadFromStore extends { parameters: object; data: object },
@@ -147,4 +148,9 @@ export type LoadableField<
147
148
  TArgs = ExtractParameters<TReadFromStore>,
148
149
  > = (
149
150
  args: TArgs | void,
151
+ // Note: fetchOptions is not nullable here because a LoadableField is not a
152
+ // user-facing API. Users should only interact with LoadableFields via APIs
153
+ // like useClientSideDefer. These APIs should have a nullable fetchOptions
154
+ // parameter, and provide a default value ({}) to the LoadableField.
155
+ fetchOptions: FetchOptions,
150
156
  ) => [StableId, Factory<FragmentReference<TReadFromStore, TResult>>];
package/src/index.ts CHANGED
@@ -74,7 +74,7 @@ export {
74
74
  logMessage,
75
75
  registerLogger,
76
76
  } from './core/logging';
77
- export { check, CheckResult, FetchOptions, FetchPolicy } from './core/check';
77
+ export { check, CheckResult, FetchOptions, ShouldFetch } from './core/check';
78
78
 
79
79
  export {
80
80
  IsographEnvironmentProvider,
@@ -6,6 +6,7 @@ import { useIsographEnvironment } from '../react/IsographEnvironmentProvider';
6
6
  import { getOrCreateItemInSuspenseCache } from '../core/cache';
7
7
  import { useLazyDisposableState } from '@isograph/react-disposable-state';
8
8
  import { LoadableField } from '../core/reader';
9
+ import { FetchOptions } from '../core/check';
9
10
 
10
11
  export function useClientSideDefer<
11
12
  TReadFromStore extends { data: object; parameters: object },
@@ -16,6 +17,7 @@ export function useClientSideDefer<
16
17
  TResult,
17
18
  ExtractParameters<TReadFromStore>
18
19
  >,
20
+ fetchOptions?: FetchOptions,
19
21
  ): { fragmentReference: FragmentReference<TReadFromStore, TResult> };
20
22
 
21
23
  export function useClientSideDefer<
@@ -29,6 +31,7 @@ export function useClientSideDefer<
29
31
  Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>
30
32
  >,
31
33
  args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>,
34
+ fetchOptions?: FetchOptions,
32
35
  ): { fragmentReference: FragmentReference<TReadFromStore, TResult> };
33
36
 
34
37
  export function useClientSideDefer<
@@ -42,8 +45,9 @@ export function useClientSideDefer<
42
45
  Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>
43
46
  >,
44
47
  args?: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs>,
48
+ fetchOptions?: FetchOptions,
45
49
  ): { fragmentReference: FragmentReference<TReadFromStore, TResult> } {
46
- const [id, loader] = loadableField(args);
50
+ const [id, loader] = loadableField(args, fetchOptions ?? {});
47
51
  const environment = useIsographEnvironment();
48
52
  const cache = getOrCreateItemInSuspenseCache(environment, id, loader);
49
53
 
@@ -19,6 +19,7 @@ import { LoadableField, type ReaderAst } from '../core/reader';
19
19
  import { useIsographEnvironment } from '../react/IsographEnvironmentProvider';
20
20
  import { useSubscribeToMultiple } from '../react/useReadAndSubscribe';
21
21
  import { maybeUnwrapNetworkRequest } from '../react/useResult';
22
+ import { FetchOptions } from '../core/check';
22
23
 
23
24
  type UsePaginationReturnValue<
24
25
  TReadFromStore extends { parameters: object; data: object },
@@ -31,7 +32,7 @@ type UsePaginationReturnValue<
31
32
  }
32
33
  | {
33
34
  kind: 'Complete';
34
- fetchMore: (count: number) => void;
35
+ fetchMore: (count: number, fetchOptions?: FetchOptions) => void;
35
36
  results: ReadonlyArray<TItem>;
36
37
  hasNextPage: boolean;
37
38
  };
@@ -178,11 +179,14 @@ export function useConnectionSpecPagination<
178
179
 
179
180
  const getFetchMore =
180
181
  (after: string | null) =>
181
- (count: number): void => {
182
- const loadedField = loadableField({
183
- after: after,
184
- first: count,
185
- })[1]();
182
+ (count: number, fetchOptions?: FetchOptions): void => {
183
+ const loadedField = loadableField(
184
+ {
185
+ after: after,
186
+ first: count,
187
+ },
188
+ fetchOptions ?? {},
189
+ )[1]();
186
190
  const newPointer = createReferenceCountedPointer(loadedField);
187
191
  const clonedPointers = loadedReferences.map(([refCountedPointer]) => {
188
192
  const clonedRefCountedPointer = refCountedPointer.cloneIfNotDisposed();
@@ -7,6 +7,7 @@ import {
7
7
  useUpdatableDisposableState,
8
8
  } from '@isograph/react-disposable-state';
9
9
  import { LoadableField } from '../core/reader';
10
+ import { FetchOptions } from '../core/check';
10
11
 
11
12
  type UseImperativeLoadableFieldReturn<
12
13
  TReadFromStore extends { data: object; parameters: object },
@@ -17,7 +18,10 @@ type UseImperativeLoadableFieldReturn<
17
18
  | FragmentReference<TReadFromStore, TResult>
18
19
  | UnassignedState;
19
20
  loadField: (
21
+ // TODO this should be void iff all args are provided by the query, like in
22
+ // useClientSideDefer.
20
23
  args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs> | void,
24
+ fetchOptions?: FetchOptions,
21
25
  ) => void;
22
26
  };
23
27
 
@@ -38,8 +42,9 @@ export function useImperativeLoadableField<
38
42
  return {
39
43
  loadField: (
40
44
  args: Omit<ExtractParameters<TReadFromStore>, keyof TProvidedArgs> | void,
45
+ fetchOptions?: FetchOptions,
41
46
  ) => {
42
- const [_id, loader] = loadableField(args);
47
+ const [_id, loader] = loadableField(args, fetchOptions ?? {});
43
48
  setState(loader());
44
49
  },
45
50
  fragmentReference: state,
@@ -17,6 +17,7 @@ import {
17
17
  import { getPromiseState, readPromise } from '../core/PromiseWrapper';
18
18
  import { type WithEncounteredRecords } from '../core/read';
19
19
  import { useSubscribeToMultiple } from '../react/useReadAndSubscribe';
20
+ import { FetchOptions } from '../core/check';
20
21
 
21
22
  type UseSkipLimitReturnValue<
22
23
  TReadFromStore extends { data: object; parameters: object },
@@ -24,7 +25,7 @@ type UseSkipLimitReturnValue<
24
25
  > =
25
26
  | {
26
27
  readonly kind: 'Complete';
27
- readonly fetchMore: (count: number) => void;
28
+ readonly fetchMore: (count: number, fetchOptions?: FetchOptions) => void;
28
29
  readonly results: ReadonlyArray<TItem>;
29
30
  }
30
31
  | {
@@ -163,11 +164,14 @@ export function useSkipLimitPagination<
163
164
 
164
165
  const getFetchMore =
165
166
  (loadedSoFar: number) =>
166
- (count: number): void => {
167
- const loadedField = loadableField({
168
- skip: loadedSoFar,
169
- limit: count,
170
- })[1]();
167
+ (count: number, fetchOptions?: FetchOptions): void => {
168
+ const loadedField = loadableField(
169
+ {
170
+ skip: loadedSoFar,
171
+ limit: count,
172
+ },
173
+ fetchOptions ?? {},
174
+ )[1]();
171
175
  const newPointer = createReferenceCountedPointer(loadedField);
172
176
  const clonedPointers = loadedReferences.map(([refCountedPointer]) => {
173
177
  const clonedRefCountedPointer = refCountedPointer.cloneIfNotDisposed();
@@ -11,7 +11,7 @@ import { useIsographEnvironment } from './IsographEnvironmentProvider';
11
11
  import { ROOT_ID } from '../core/IsographEnvironment';
12
12
  import { maybeMakeNetworkRequest } from '../core/makeNetworkRequest';
13
13
  import { wrapResolvedValue } from '../core/PromiseWrapper';
14
- import { DEFAULT_FETCH_POLICY, FetchOptions } from '../core/check';
14
+ import { DEFAULT_SHOULD_FETCH_VALUE, FetchOptions } from '../core/check';
15
15
 
16
16
  // TODO rename this to useImperativelyLoadedEntrypoint
17
17
 
@@ -26,7 +26,7 @@ export function useImperativeReference<
26
26
  | UnassignedState;
27
27
  loadFragmentReference: (
28
28
  variables: ExtractParameters<TReadFromStore>,
29
- options?: FetchOptions,
29
+ fetchOptions?: FetchOptions,
30
30
  ) => void;
31
31
  } {
32
32
  const { state, setState } =
@@ -38,14 +38,15 @@ export function useImperativeReference<
38
38
  fragmentReference: state,
39
39
  loadFragmentReference: (
40
40
  variables: ExtractParameters<TReadFromStore>,
41
- options?: FetchOptions,
41
+ fetchOptions?: FetchOptions,
42
42
  ) => {
43
- const fetchPolicy = options?.fetchPolicy ?? DEFAULT_FETCH_POLICY;
43
+ const shouldFetch =
44
+ fetchOptions?.shouldFetch ?? DEFAULT_SHOULD_FETCH_VALUE;
44
45
  const [networkRequest, disposeNetworkRequest] = maybeMakeNetworkRequest(
45
46
  environment,
46
47
  entrypoint,
47
48
  variables,
48
- fetchPolicy,
49
+ shouldFetch,
49
50
  );
50
51
  setState([
51
52
  {
@@ -15,7 +15,7 @@ export function useLazyReference<
15
15
  >(
16
16
  entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>,
17
17
  variables: ExtractParameters<TReadFromStore>,
18
- options?: FetchOptions,
18
+ fetchOptions?: FetchOptions,
19
19
  ): {
20
20
  fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>;
21
21
  } {
@@ -33,7 +33,7 @@ export function useLazyReference<
33
33
  environment,
34
34
  entrypoint,
35
35
  variables,
36
- options,
36
+ fetchOptions,
37
37
  );
38
38
 
39
39
  return {