@isograph/react 0.2.0 → 0.3.0
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/dist/core/FragmentReference.d.ts +14 -4
- package/dist/core/FragmentReference.d.ts.map +1 -0
- package/dist/core/FragmentReference.js +2 -3
- package/dist/core/IsographEnvironment.d.ts +28 -10
- package/dist/core/IsographEnvironment.d.ts.map +1 -0
- package/dist/core/IsographEnvironment.js +15 -22
- package/dist/core/PromiseWrapper.d.ts +1 -0
- package/dist/core/PromiseWrapper.d.ts.map +1 -0
- package/dist/core/PromiseWrapper.js +4 -5
- package/dist/core/areEqualWithDeepComparison.d.ts +5 -3
- package/dist/core/areEqualWithDeepComparison.d.ts.map +1 -0
- package/dist/core/areEqualWithDeepComparison.js +73 -39
- package/dist/core/cache.d.ts +26 -10
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +160 -98
- package/dist/core/check.d.ts +18 -0
- package/dist/core/check.d.ts.map +1 -0
- package/dist/core/check.js +127 -0
- package/dist/core/componentCache.d.ts +1 -1
- package/dist/core/componentCache.d.ts.map +1 -0
- package/dist/core/componentCache.js +14 -14
- package/dist/core/entrypoint.d.ts +27 -8
- package/dist/core/entrypoint.d.ts.map +1 -0
- package/dist/core/entrypoint.js +1 -2
- package/dist/core/garbageCollection.d.ts +3 -1
- package/dist/core/garbageCollection.d.ts.map +1 -0
- package/dist/core/garbageCollection.js +48 -15
- package/dist/core/logging.d.ts +69 -0
- package/dist/core/logging.d.ts.map +1 -0
- package/dist/core/logging.js +19 -0
- package/dist/core/makeNetworkRequest.d.ts +4 -1
- package/dist/core/makeNetworkRequest.d.ts.map +1 -0
- package/dist/core/makeNetworkRequest.js +71 -15
- package/dist/core/read.d.ts +20 -5
- package/dist/core/read.d.ts.map +1 -0
- package/dist/core/read.js +104 -41
- package/dist/core/reader.d.ts +34 -10
- package/dist/core/reader.d.ts.map +1 -0
- package/dist/core/util.d.ts +2 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -2
- package/dist/loadable-hooks/useClientSideDefer.d.ts +15 -3
- package/dist/loadable-hooks/useClientSideDefer.d.ts.map +1 -0
- package/dist/loadable-hooks/useClientSideDefer.js +4 -6
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts +34 -0
- package/dist/loadable-hooks/useConnectionSpecPagination.d.ts.map +1 -0
- package/dist/loadable-hooks/useConnectionSpecPagination.js +160 -0
- package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts +1 -0
- package/dist/loadable-hooks/useImperativeExposedMutationField.d.ts.map +1 -0
- package/dist/loadable-hooks/useImperativeExposedMutationField.js +1 -2
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts +13 -5
- package/dist/loadable-hooks/useImperativeLoadableField.d.ts.map +1 -0
- package/dist/loadable-hooks/useImperativeLoadableField.js +3 -4
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts +18 -24
- package/dist/loadable-hooks/useSkipLimitPagination.d.ts.map +1 -0
- package/dist/loadable-hooks/useSkipLimitPagination.js +88 -44
- package/dist/react/FragmentReader.d.ts +7 -4
- package/dist/react/FragmentReader.d.ts.map +1 -0
- package/dist/react/FragmentReader.js +4 -2
- package/dist/react/IsographEnvironmentProvider.d.ts +1 -0
- package/dist/react/IsographEnvironmentProvider.d.ts.map +1 -0
- package/dist/react/IsographEnvironmentProvider.js +3 -3
- package/dist/react/RenderAfterCommit__DO_NOT_USE.d.ts +10 -0
- package/dist/react/RenderAfterCommit__DO_NOT_USE.d.ts.map +1 -0
- package/dist/react/RenderAfterCommit__DO_NOT_USE.js +15 -0
- package/dist/react/useImperativeReference.d.ts +8 -3
- package/dist/react/useImperativeReference.d.ts.map +1 -0
- package/dist/react/useImperativeReference.js +4 -5
- package/dist/react/useLazyReference.d.ts +7 -2
- package/dist/react/useLazyReference.d.ts.map +1 -0
- package/dist/react/useLazyReference.js +11 -4
- package/dist/react/useReadAndSubscribe.d.ts +12 -3
- package/dist/react/useReadAndSubscribe.d.ts.map +1 -0
- package/dist/react/useReadAndSubscribe.js +6 -7
- package/dist/react/useRerenderOnChange.d.ts +6 -1
- package/dist/react/useRerenderOnChange.d.ts.map +1 -0
- package/dist/react/useRerenderOnChange.js +3 -4
- package/dist/react/useResult.d.ts +5 -1
- package/dist/react/useResult.d.ts.map +1 -0
- package/dist/react/useResult.js +8 -5
- package/{src/tests/isograph.config.json → isograph.config.json} +1 -1
- package/package.json +12 -8
- package/{src/tests/schema.graphql → schema.graphql} +1 -0
- package/src/core/FragmentReference.ts +17 -5
- package/src/core/IsographEnvironment.ts +38 -29
- package/src/core/areEqualWithDeepComparison.ts +76 -42
- package/src/core/cache.ts +237 -123
- package/src/core/check.ts +207 -0
- package/src/core/componentCache.ts +18 -17
- package/src/core/entrypoint.ts +15 -8
- package/src/core/garbageCollection.ts +71 -20
- package/src/core/logging.ts +116 -0
- package/src/core/makeNetworkRequest.ts +89 -13
- package/src/core/read.ts +162 -55
- package/src/core/reader.ts +40 -13
- package/src/core/util.ts +4 -0
- package/src/index.ts +14 -1
- package/src/loadable-hooks/useClientSideDefer.ts +45 -15
- package/src/loadable-hooks/useConnectionSpecPagination.ts +331 -0
- package/src/loadable-hooks/useImperativeLoadableField.ts +36 -10
- package/src/loadable-hooks/useSkipLimitPagination.ts +231 -90
- package/src/react/FragmentReader.tsx +13 -4
- package/src/react/RenderAfterCommit__DO_NOT_USE.tsx +17 -0
- package/src/react/useImperativeReference.ts +18 -7
- package/src/react/useLazyReference.ts +24 -4
- package/src/react/useReadAndSubscribe.ts +20 -5
- package/src/react/useRerenderOnChange.ts +6 -1
- package/src/react/useResult.ts +10 -2
- package/src/tests/__isograph/Query/meName/entrypoint.ts +7 -2
- package/src/tests/__isograph/Query/meName/param_type.ts +5 -2
- package/src/tests/__isograph/Query/meName/resolver_reader.ts +1 -0
- package/src/tests/__isograph/Query/meNameSuccessor/entrypoint.ts +9 -2
- package/src/tests/__isograph/Query/meNameSuccessor/param_type.ts +9 -6
- package/src/tests/__isograph/Query/meNameSuccessor/resolver_reader.ts +3 -0
- package/src/tests/__isograph/Query/nodeField/entrypoint.ts +13 -2
- package/src/tests/__isograph/Query/nodeField/param_type.ts +7 -3
- package/src/tests/__isograph/Query/nodeField/parameters_type.ts +3 -0
- package/src/tests/__isograph/Query/nodeField/resolver_reader.ts +1 -0
- package/src/tests/__isograph/Query/subquery/entrypoint.ts +67 -0
- package/src/tests/__isograph/Query/subquery/output_type.ts +3 -0
- package/src/tests/__isograph/Query/subquery/param_type.ts +12 -0
- package/src/tests/__isograph/Query/subquery/parameters_type.ts +3 -0
- package/src/tests/__isograph/Query/subquery/resolver_reader.ts +47 -0
- package/src/tests/__isograph/iso.ts +22 -11
- package/src/tests/garbageCollection.test.ts +45 -39
- package/src/tests/meNameSuccessor.ts +8 -3
- package/src/tests/nodeQuery.ts +6 -4
- package/src/tests/normalizeData.test.ts +120 -0
- package/src/tests/tsconfig.json +3 -3
- package/tsconfig.json +2 -2
- package/tsconfig.pkg.json +6 -1
- package/vitest.config.ts +20 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.useImperativeReference =
|
3
|
+
exports.useImperativeReference = useImperativeReference;
|
4
4
|
const react_disposable_state_1 = require("@isograph/react-disposable-state");
|
5
5
|
const IsographEnvironmentProvider_1 = require("./IsographEnvironmentProvider");
|
6
6
|
const IsographEnvironment_1 = require("../core/IsographEnvironment");
|
@@ -12,8 +12,8 @@ function useImperativeReference(entrypoint) {
|
|
12
12
|
const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
|
13
13
|
return {
|
14
14
|
fragmentReference: state,
|
15
|
-
loadFragmentReference: (variables) => {
|
16
|
-
const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.
|
15
|
+
loadFragmentReference: (variables, fetchOptions) => {
|
16
|
+
const [networkRequest, disposeNetworkRequest] = (0, makeNetworkRequest_1.maybeMakeNetworkRequest)(environment, entrypoint, variables, fetchOptions);
|
17
17
|
setState([
|
18
18
|
{
|
19
19
|
kind: 'FragmentReference',
|
@@ -22,7 +22,7 @@ function useImperativeReference(entrypoint) {
|
|
22
22
|
readerArtifact: entrypoint.readerWithRefetchQueries.readerArtifact,
|
23
23
|
nestedRefetchQueries: entrypoint.readerWithRefetchQueries.nestedRefetchQueries,
|
24
24
|
}),
|
25
|
-
root: IsographEnvironment_1.ROOT_ID,
|
25
|
+
root: { __link: IsographEnvironment_1.ROOT_ID, __typename: entrypoint.concreteType },
|
26
26
|
variables,
|
27
27
|
networkRequest,
|
28
28
|
},
|
@@ -33,4 +33,3 @@ function useImperativeReference(entrypoint) {
|
|
33
33
|
},
|
34
34
|
};
|
35
35
|
}
|
36
|
-
exports.useImperativeReference = useImperativeReference;
|
@@ -1,5 +1,10 @@
|
|
1
|
-
import { FragmentReference,
|
1
|
+
import { FragmentReference, ExtractParameters } from '../core/FragmentReference';
|
2
2
|
import { IsographEntrypoint } from '../core/entrypoint';
|
3
|
-
|
3
|
+
import { FetchOptions } from '../core/check';
|
4
|
+
export declare function useLazyReference<TReadFromStore extends {
|
5
|
+
parameters: object;
|
6
|
+
data: object;
|
7
|
+
}, TClientFieldValue>(entrypoint: IsographEntrypoint<TReadFromStore, TClientFieldValue>, variables: ExtractParameters<TReadFromStore>, fetchOptions?: FetchOptions): {
|
4
8
|
fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>;
|
5
9
|
};
|
10
|
+
//# sourceMappingURL=useLazyReference.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useLazyReference.d.ts","sourceRoot":"","sources":["../../src/react/useLazyReference.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,wBAAgB,gBAAgB,CAC9B,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC3D,iBAAiB,EAEjB,UAAU,EAAE,kBAAkB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EACjE,SAAS,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAC5C,YAAY,CAAC,EAAE,YAAY,GAC1B;IACD,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;CACzE,CAqBA"}
|
@@ -1,14 +1,21 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.useLazyReference =
|
3
|
+
exports.useLazyReference = useLazyReference;
|
4
4
|
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, fetchOptions) {
|
8
9
|
const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
|
9
|
-
|
10
|
+
if ((entrypoint === null || entrypoint === void 0 ? void 0 : entrypoint.kind) !== 'Entrypoint') {
|
11
|
+
// TODO have a separate error logger
|
12
|
+
(0, logging_1.logMessage)(environment, {
|
13
|
+
kind: 'NonEntrypointReceived',
|
14
|
+
entrypoint,
|
15
|
+
});
|
16
|
+
}
|
17
|
+
const cache = (0, cache_1.getOrCreateCacheForArtifact)(environment, entrypoint, variables, fetchOptions);
|
10
18
|
return {
|
11
19
|
fragmentReference: (0, react_disposable_state_1.useLazyDisposableState)(cache).state,
|
12
20
|
};
|
13
21
|
}
|
14
|
-
exports.useLazyReference = useLazyReference;
|
@@ -1,11 +1,20 @@
|
|
1
|
-
import { FragmentReference } from '../core/FragmentReference';
|
1
|
+
import { FragmentReference, ExtractData } from '../core/FragmentReference';
|
2
2
|
import { NetworkRequestReaderOptions, WithEncounteredRecords } from '../core/read';
|
3
|
+
import type { ReaderAst } from '../core/reader';
|
3
4
|
/**
|
4
5
|
* Read the data from a fragment reference and subscribe to updates.
|
5
6
|
*/
|
6
|
-
export declare function useReadAndSubscribe<TReadFromStore extends
|
7
|
-
|
7
|
+
export declare function useReadAndSubscribe<TReadFromStore extends {
|
8
|
+
parameters: object;
|
9
|
+
data: object;
|
10
|
+
}>(fragmentReference: FragmentReference<TReadFromStore, any>, networkRequestOptions: NetworkRequestReaderOptions, readerAst: ReaderAst<TReadFromStore>): ExtractData<TReadFromStore>;
|
11
|
+
export declare function useSubscribeToMultiple<TReadFromStore extends {
|
12
|
+
parameters: object;
|
13
|
+
data: object;
|
14
|
+
}>(items: ReadonlyArray<{
|
8
15
|
records: WithEncounteredRecords<TReadFromStore>;
|
9
16
|
callback: (updatedRecords: WithEncounteredRecords<TReadFromStore>) => void;
|
10
17
|
fragmentReference: FragmentReference<TReadFromStore, any>;
|
18
|
+
readerAst: ReaderAst<TReadFromStore>;
|
11
19
|
}>): void;
|
20
|
+
//# sourceMappingURL=useReadAndSubscribe.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useReadAndSubscribe.d.ts","sourceRoot":"","sources":["../../src/react/useReadAndSubscribe.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAEjB,WAAW,EACZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,2BAA2B,EAE3B,sBAAsB,EACvB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAE3D,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,GAAG,CAAC,EACzD,qBAAqB,EAAE,2BAA2B,EAClD,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,GACnC,WAAW,CAAC,cAAc,CAAC,CAY7B;AAED,wBAAgB,sBAAsB,CACpC,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAE3D,KAAK,EAAE,aAAa,CAAC;IACnB,OAAO,EAAE,sBAAsB,CAAC,cAAc,CAAC,CAAC;IAChD,QAAQ,EAAE,CAAC,cAAc,EAAE,sBAAsB,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC3E,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAC1D,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;CACtC,CAAC,QAiCH"}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.useReadAndSubscribe = useReadAndSubscribe;
|
4
|
+
exports.useSubscribeToMultiple = useSubscribeToMultiple;
|
4
5
|
const react_1 = require("react");
|
5
6
|
const FragmentReference_1 = require("../core/FragmentReference");
|
6
7
|
const read_1 = require("../core/read");
|
@@ -10,18 +11,17 @@ const cache_1 = require("../core/cache");
|
|
10
11
|
/**
|
11
12
|
* Read the data from a fragment reference and subscribe to updates.
|
12
13
|
*/
|
13
|
-
function useReadAndSubscribe(fragmentReference, networkRequestOptions) {
|
14
|
+
function useReadAndSubscribe(fragmentReference, networkRequestOptions, readerAst) {
|
14
15
|
const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
|
15
16
|
const [readOutDataAndRecords, setReadOutDataAndRecords] = (0, react_1.useState)(() => (0, read_1.readButDoNotEvaluate)(environment, fragmentReference, networkRequestOptions));
|
16
|
-
(0, useRerenderOnChange_1.useRerenderOnChange)(readOutDataAndRecords, fragmentReference, setReadOutDataAndRecords);
|
17
|
+
(0, useRerenderOnChange_1.useRerenderOnChange)(readOutDataAndRecords, fragmentReference, setReadOutDataAndRecords, readerAst);
|
17
18
|
return readOutDataAndRecords.item;
|
18
19
|
}
|
19
|
-
exports.useReadAndSubscribe = useReadAndSubscribe;
|
20
20
|
function useSubscribeToMultiple(items) {
|
21
21
|
const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
|
22
22
|
(0, react_1.useEffect)(() => {
|
23
|
-
const cleanupFns = items.map(({ records, callback, fragmentReference }) => {
|
24
|
-
return (0, cache_1.subscribe)(environment, records, fragmentReference, callback);
|
23
|
+
const cleanupFns = items.map(({ records, callback, fragmentReference, readerAst }) => {
|
24
|
+
return (0, cache_1.subscribe)(environment, records, fragmentReference, callback, readerAst);
|
25
25
|
});
|
26
26
|
return () => {
|
27
27
|
cleanupFns.forEach((loader) => {
|
@@ -38,4 +38,3 @@ function useSubscribeToMultiple(items) {
|
|
38
38
|
.join('.'),
|
39
39
|
]);
|
40
40
|
}
|
41
|
-
exports.useSubscribeToMultiple = useSubscribeToMultiple;
|
@@ -1,3 +1,8 @@
|
|
1
1
|
import { WithEncounteredRecords } from '../core/read';
|
2
2
|
import { FragmentReference } from '../core/FragmentReference';
|
3
|
-
|
3
|
+
import type { ReaderAst } from '../core/reader';
|
4
|
+
export declare function useRerenderOnChange<TReadFromStore extends {
|
5
|
+
parameters: object;
|
6
|
+
data: object;
|
7
|
+
}>(encounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>, fragmentReference: FragmentReference<any, any>, setEncounteredDataAndRecords: (data: WithEncounteredRecords<TReadFromStore>) => void, readerAst: ReaderAst<TReadFromStore>): void;
|
8
|
+
//# sourceMappingURL=useRerenderOnChange.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useRerenderOnChange.d.ts","sourceRoot":"","sources":["../../src/react/useRerenderOnChange.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD,wBAAgB,mBAAmB,CACjC,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAE3D,yBAAyB,EAAE,sBAAsB,CAAC,cAAc,CAAC,EACjE,iBAAiB,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,EAC9C,4BAA4B,EAAE,CAC5B,IAAI,EAAE,sBAAsB,CAAC,cAAc,CAAC,KACzC,IAAI,EACT,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,QAoBrC"}
|
@@ -1,17 +1,17 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.useRerenderOnChange =
|
3
|
+
exports.useRerenderOnChange = useRerenderOnChange;
|
4
4
|
const react_1 = require("react");
|
5
5
|
const cache_1 = require("../core/cache");
|
6
6
|
const IsographEnvironmentProvider_1 = require("./IsographEnvironmentProvider");
|
7
7
|
// TODO add unit tests for this. Add integration tests that test
|
8
8
|
// behavior when the encounteredRecords underneath a fragment change.
|
9
|
-
function useRerenderOnChange(encounteredDataAndRecords, fragmentReference, setEncounteredDataAndRecords) {
|
9
|
+
function useRerenderOnChange(encounteredDataAndRecords, fragmentReference, setEncounteredDataAndRecords, readerAst) {
|
10
10
|
const environment = (0, IsographEnvironmentProvider_1.useIsographEnvironment)();
|
11
11
|
(0, react_1.useEffect)(() => {
|
12
12
|
return (0, cache_1.subscribe)(environment, encounteredDataAndRecords, fragmentReference, (newEncounteredDataAndRecords) => {
|
13
13
|
setEncounteredDataAndRecords(newEncounteredDataAndRecords);
|
14
|
-
});
|
14
|
+
}, readerAst);
|
15
15
|
// Note: this is an empty array on purpose:
|
16
16
|
// - the fragment reference is stable for the life of the component
|
17
17
|
// - ownership of encounteredDataAndRecords is transferred into the
|
@@ -20,4 +20,3 @@ function useRerenderOnChange(encounteredDataAndRecords, fragmentReference, setEn
|
|
20
20
|
// the dependency array
|
21
21
|
}, []);
|
22
22
|
}
|
23
|
-
exports.useRerenderOnChange = useRerenderOnChange;
|
@@ -1,5 +1,9 @@
|
|
1
1
|
import { FragmentReference } from '../core/FragmentReference';
|
2
2
|
import { NetworkRequestReaderOptions } from '../core/read';
|
3
3
|
import { PromiseWrapper } from '../core/PromiseWrapper';
|
4
|
-
export declare function useResult<TReadFromStore extends
|
4
|
+
export declare function useResult<TReadFromStore extends {
|
5
|
+
parameters: object;
|
6
|
+
data: object;
|
7
|
+
}, TClientFieldValue>(fragmentReference: FragmentReference<TReadFromStore, TClientFieldValue>, partialNetworkRequestOptions?: Partial<NetworkRequestReaderOptions> | void): TClientFieldValue;
|
5
8
|
export declare function maybeUnwrapNetworkRequest(networkRequest: PromiseWrapper<void, any>, networkRequestOptions: NetworkRequestReaderOptions): void;
|
9
|
+
//# sourceMappingURL=useResult.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"useResult.d.ts","sourceRoot":"","sources":["../../src/react/useResult.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAEL,2BAA2B,EAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EAEL,cAAc,EAEf,MAAM,wBAAwB,CAAC;AAEhC,wBAAgB,SAAS,CACvB,cAAc,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAC3D,iBAAiB,EAEjB,iBAAiB,EAAE,iBAAiB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EACvE,4BAA4B,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,GACzE,iBAAiB,CAqCnB;AAED,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,EACzC,qBAAqB,EAAE,2BAA2B,QAWnD"}
|
package/dist/react/useResult.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.useResult = useResult;
|
4
|
+
exports.maybeUnwrapNetworkRequest = maybeUnwrapNetworkRequest;
|
4
5
|
const IsographEnvironmentProvider_1 = require("../react/IsographEnvironmentProvider");
|
5
6
|
const componentCache_1 = require("../core/componentCache");
|
6
7
|
const useReadAndSubscribe_1 = require("./useReadAndSubscribe");
|
@@ -17,12 +18,15 @@ function useResult(fragmentReference, partialNetworkRequestOptions) {
|
|
17
18
|
return (0, componentCache_1.getOrCreateCachedComponent)(environment, readerWithRefetchQueries.readerArtifact.componentName, fragmentReference, networkRequestOptions);
|
18
19
|
}
|
19
20
|
case 'EagerReaderArtifact': {
|
20
|
-
const data = (0, useReadAndSubscribe_1.useReadAndSubscribe)(fragmentReference, networkRequestOptions);
|
21
|
-
|
21
|
+
const data = (0, useReadAndSubscribe_1.useReadAndSubscribe)(fragmentReference, networkRequestOptions, readerWithRefetchQueries.readerArtifact.readerAst);
|
22
|
+
const param = {
|
23
|
+
data: data,
|
24
|
+
parameters: fragmentReference.variables,
|
25
|
+
};
|
26
|
+
return readerWithRefetchQueries.readerArtifact.resolver(param);
|
22
27
|
}
|
23
28
|
}
|
24
29
|
}
|
25
|
-
exports.useResult = useResult;
|
26
30
|
function maybeUnwrapNetworkRequest(networkRequest, networkRequestOptions) {
|
27
31
|
const state = (0, PromiseWrapper_1.getPromiseState)(networkRequest);
|
28
32
|
if (state.kind === 'Err' && networkRequestOptions.throwOnNetworkError) {
|
@@ -33,4 +37,3 @@ function maybeUnwrapNetworkRequest(networkRequest, networkRequestOptions) {
|
|
33
37
|
throw state.promise;
|
34
38
|
}
|
35
39
|
}
|
36
|
-
exports.maybeUnwrapNetworkRequest = maybeUnwrapNetworkRequest;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@isograph/react",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.3.0",
|
4
4
|
"description": "Use Isograph with React",
|
5
5
|
"homepage": "https://isograph.dev",
|
6
6
|
"main": "dist/index.js",
|
@@ -13,22 +13,26 @@
|
|
13
13
|
"test": "vitest run",
|
14
14
|
"test-watch": "vitest watch",
|
15
15
|
"coverage": "vitest run --coverage",
|
16
|
-
"prepack": "
|
17
|
-
"tsc": "tsc"
|
16
|
+
"prepack": "pnpm run test && pnpm run compile",
|
17
|
+
"tsc": "tsc",
|
18
|
+
"iso": "../../target/debug/isograph_cli --config ./isograph.config.json",
|
19
|
+
"iso-watch": "../../target/debug/isograph_cli --config ./isograph.config.json --watch"
|
18
20
|
},
|
19
21
|
"dependencies": {
|
20
|
-
"@isograph/disposable-types": "
|
22
|
+
"@isograph/disposable-types": "*",
|
21
23
|
"@isograph/react-disposable-state": "*",
|
22
24
|
"@isograph/reference-counted-pointer": "*"
|
23
25
|
},
|
24
26
|
"peerDependencies": {
|
25
|
-
"react": "18.
|
27
|
+
"react": "18.3.1"
|
26
28
|
},
|
27
29
|
"devDependencies": {
|
28
|
-
"@
|
30
|
+
"@babel/preset-typescript": "^7.24.7",
|
31
|
+
"@types/react": "18.3.1",
|
29
32
|
"react-test-renderer": "^18.2.0",
|
30
|
-
"
|
31
|
-
"
|
33
|
+
"typescript": "5.6.3",
|
34
|
+
"vite-plugin-babel": "^1.2.0",
|
35
|
+
"vite-plugin-commonjs": "^0.10.1"
|
32
36
|
},
|
33
37
|
"repository": {
|
34
38
|
"type": "git",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { type Link } from './IsographEnvironment';
|
2
2
|
import { ReaderWithRefetchQueries } from '../core/entrypoint';
|
3
3
|
import { PromiseWrapper } from './PromiseWrapper';
|
4
4
|
|
@@ -7,23 +7,35 @@ export type VariableValue = string | number | boolean | null | object;
|
|
7
7
|
|
8
8
|
export type Variables = { readonly [index: string]: VariableValue };
|
9
9
|
|
10
|
+
export type ExtractData<T> = T extends {
|
11
|
+
data: infer D extends object;
|
12
|
+
}
|
13
|
+
? D
|
14
|
+
: never;
|
15
|
+
|
16
|
+
export type ExtractParameters<T> = T extends {
|
17
|
+
parameters: infer P extends Variables;
|
18
|
+
}
|
19
|
+
? P
|
20
|
+
: Variables;
|
21
|
+
|
10
22
|
export type FragmentReference<
|
11
|
-
TReadFromStore extends
|
23
|
+
TReadFromStore extends { parameters: object; data: object },
|
12
24
|
TClientFieldValue,
|
13
25
|
> = {
|
14
26
|
readonly kind: 'FragmentReference';
|
15
27
|
readonly readerWithRefetchQueries: PromiseWrapper<
|
16
28
|
ReaderWithRefetchQueries<TReadFromStore, TClientFieldValue>
|
17
29
|
>;
|
18
|
-
readonly root:
|
19
|
-
readonly variables:
|
30
|
+
readonly root: Link;
|
31
|
+
readonly variables: ExtractParameters<TReadFromStore>;
|
20
32
|
readonly networkRequest: PromiseWrapper<void, any>;
|
21
33
|
};
|
22
34
|
|
23
35
|
export function stableIdForFragmentReference(
|
24
36
|
fragmentReference: FragmentReference<any, any>,
|
25
37
|
): string {
|
26
|
-
return `${fragmentReference.root}/TODO_FRAGMENT_NAME/${serializeVariables(fragmentReference.variables ?? {})}`;
|
38
|
+
return `${fragmentReference.root.__typename}/${fragmentReference.root.__link}/TODO_FRAGMENT_NAME/${serializeVariables(fragmentReference.variables ?? {})}`;
|
27
39
|
}
|
28
40
|
|
29
41
|
function serializeVariables(variables: Variables) {
|
@@ -4,6 +4,8 @@ import { WithEncounteredRecords } from './read';
|
|
4
4
|
import { FragmentReference, Variables } from './FragmentReference';
|
5
5
|
import { PromiseWrapper, wrapPromise } from './PromiseWrapper';
|
6
6
|
import { IsographEntrypoint } from './entrypoint';
|
7
|
+
import type { ReaderAst } from './reader';
|
8
|
+
import { LogFunction, WrappedLogFunction } from './logging';
|
7
9
|
|
8
10
|
export type ComponentOrFieldName = string;
|
9
11
|
export type StringifiedArgs = string;
|
@@ -13,7 +15,9 @@ type ComponentCache = {
|
|
13
15
|
};
|
14
16
|
};
|
15
17
|
|
16
|
-
export type FragmentSubscription<
|
18
|
+
export type FragmentSubscription<
|
19
|
+
TReadFromStore extends { parameters: object; data: object },
|
20
|
+
> = {
|
17
21
|
readonly kind: 'FragmentSubscription';
|
18
22
|
readonly callback: (
|
19
23
|
newEncounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>,
|
@@ -21,13 +25,24 @@ export type FragmentSubscription<TReadFromStore extends Object> = {
|
|
21
25
|
/** The value read out from the previous call to readButDoNotEvaluate */
|
22
26
|
readonly encounteredDataAndRecords: WithEncounteredRecords<TReadFromStore>;
|
23
27
|
readonly fragmentReference: FragmentReference<TReadFromStore, any>;
|
28
|
+
readonly readerAst: ReaderAst<TReadFromStore>;
|
24
29
|
};
|
30
|
+
|
31
|
+
type AnyChangesToRecordSubscription = {
|
32
|
+
readonly kind: 'AnyChangesToRecord';
|
33
|
+
readonly callback: () => void;
|
34
|
+
readonly recordLink: Link;
|
35
|
+
};
|
36
|
+
|
25
37
|
type AnyRecordSubscription = {
|
26
38
|
readonly kind: 'AnyRecords';
|
27
39
|
readonly callback: () => void;
|
28
40
|
};
|
29
41
|
|
30
|
-
type Subscription =
|
42
|
+
type Subscription =
|
43
|
+
| FragmentSubscription<{ parameters: object; data: object }>
|
44
|
+
| AnyChangesToRecordSubscription
|
45
|
+
| AnyRecordSubscription;
|
31
46
|
type Subscriptions = Set<Subscription>;
|
32
47
|
// Should this be a map?
|
33
48
|
type CacheMap<T> = { [index: string]: ParentCache<T> };
|
@@ -49,11 +64,12 @@ export type IsographEnvironment = {
|
|
49
64
|
readonly retainedQueries: Set<RetainedQuery>;
|
50
65
|
readonly gcBuffer: Array<RetainedQuery>;
|
51
66
|
readonly gcBufferSize: number;
|
67
|
+
readonly loggers: Set<WrappedLogFunction>;
|
52
68
|
};
|
53
69
|
|
54
70
|
export type MissingFieldHandler = (
|
55
71
|
storeRecord: StoreRecord,
|
56
|
-
root:
|
72
|
+
root: Link,
|
57
73
|
fieldName: string,
|
58
74
|
arguments_: { [index: string]: any } | null,
|
59
75
|
variables: Variables | null,
|
@@ -66,6 +82,7 @@ export type IsographNetworkFunction = (
|
|
66
82
|
|
67
83
|
export type Link = {
|
68
84
|
readonly __link: DataId;
|
85
|
+
readonly __typename: TypeName;
|
69
86
|
};
|
70
87
|
|
71
88
|
export type DataTypeValue =
|
@@ -89,20 +106,26 @@ export type StoreRecord = {
|
|
89
106
|
readonly id?: DataId;
|
90
107
|
};
|
91
108
|
|
109
|
+
export type TypeName = string;
|
92
110
|
export type DataId = string;
|
93
111
|
|
94
112
|
export const ROOT_ID: DataId & '__ROOT' = '__ROOT';
|
95
113
|
|
96
114
|
export type IsographStore = {
|
97
|
-
[index:
|
98
|
-
|
115
|
+
[index: TypeName]: {
|
116
|
+
[index: DataId]: StoreRecord | null;
|
117
|
+
} | null;
|
118
|
+
readonly Query: {
|
119
|
+
readonly __ROOT: StoreRecord;
|
120
|
+
};
|
99
121
|
};
|
100
122
|
|
101
123
|
const DEFAULT_GC_BUFFER_SIZE = 10;
|
102
124
|
export function createIsographEnvironment(
|
103
125
|
store: IsographStore,
|
104
126
|
networkFunction: IsographNetworkFunction,
|
105
|
-
missingFieldHandler?: MissingFieldHandler,
|
127
|
+
missingFieldHandler?: MissingFieldHandler | null,
|
128
|
+
logFunction?: LogFunction | null,
|
106
129
|
): IsographEnvironment {
|
107
130
|
return {
|
108
131
|
store,
|
@@ -115,34 +138,18 @@ export function createIsographEnvironment(
|
|
115
138
|
retainedQueries: new Set(),
|
116
139
|
gcBuffer: [],
|
117
140
|
gcBufferSize: DEFAULT_GC_BUFFER_SIZE,
|
141
|
+
loggers: logFunction != null ? new Set([{ log: logFunction }]) : new Set(),
|
118
142
|
};
|
119
143
|
}
|
120
144
|
|
121
145
|
export function createIsographStore(): IsographStore {
|
122
146
|
return {
|
123
|
-
|
147
|
+
Query: {
|
148
|
+
[ROOT_ID]: {},
|
149
|
+
},
|
124
150
|
};
|
125
151
|
}
|
126
152
|
|
127
|
-
export function defaultMissingFieldHandler(
|
128
|
-
_storeRecord: StoreRecord,
|
129
|
-
_root: DataId,
|
130
|
-
fieldName: string,
|
131
|
-
arguments_: { [index: string]: any } | null,
|
132
|
-
variables: Variables | null,
|
133
|
-
): Link | undefined {
|
134
|
-
if (fieldName === 'node' || fieldName === 'user') {
|
135
|
-
const variable = arguments_?.['id'];
|
136
|
-
const value = variables?.[variable];
|
137
|
-
|
138
|
-
// TODO can we handle explicit nulls here too? Probably, after wrapping in objects
|
139
|
-
if (value != null) {
|
140
|
-
// @ts-expect-error
|
141
|
-
return { __link: value };
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
153
|
export function assertLink(link: DataTypeValue): Link | null | undefined {
|
147
154
|
if (Array.isArray(link)) {
|
148
155
|
throw new Error('Unexpected array');
|
@@ -160,10 +167,12 @@ export function getLink(maybeLink: DataTypeValue): Link | null {
|
|
160
167
|
if (
|
161
168
|
maybeLink != null &&
|
162
169
|
typeof maybeLink === 'object' &&
|
163
|
-
|
164
|
-
maybeLink.__link != null
|
170
|
+
'__link' in maybeLink &&
|
171
|
+
maybeLink.__link != null &&
|
172
|
+
'__typename' in maybeLink &&
|
173
|
+
maybeLink.__typename != null
|
165
174
|
) {
|
166
|
-
return maybeLink
|
175
|
+
return maybeLink;
|
167
176
|
}
|
168
177
|
return null;
|
169
178
|
}
|
@@ -1,78 +1,112 @@
|
|
1
|
-
|
1
|
+
import type { ReaderAst, ReaderLinkedField, ReaderScalarField } from './reader';
|
2
|
+
export function mergeUsingReaderAst(
|
3
|
+
field: ReaderScalarField | ReaderLinkedField,
|
2
4
|
oldItem: unknown,
|
3
5
|
newItem: unknown,
|
4
|
-
):
|
6
|
+
): unknown {
|
5
7
|
if (newItem === null) {
|
6
|
-
return oldItem === null;
|
8
|
+
return oldItem === null ? oldItem : newItem;
|
7
9
|
}
|
8
10
|
|
9
11
|
if (newItem === undefined) {
|
10
|
-
return oldItem === undefined;
|
12
|
+
return oldItem === undefined ? oldItem : newItem;
|
11
13
|
}
|
12
14
|
|
13
15
|
if (Array.isArray(newItem)) {
|
14
16
|
if (!Array.isArray(oldItem)) {
|
15
|
-
return
|
17
|
+
return newItem;
|
16
18
|
}
|
17
19
|
|
18
|
-
return
|
20
|
+
return mergeArraysUsingReaderAst(field, oldItem, newItem);
|
19
21
|
}
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
return
|
24
|
-
|
23
|
+
switch (field.kind) {
|
24
|
+
case 'Scalar':
|
25
|
+
return oldItem === newItem ? oldItem : newItem;
|
26
|
+
case 'Linked':
|
27
|
+
if (oldItem == null) {
|
28
|
+
return newItem;
|
29
|
+
}
|
25
30
|
|
26
|
-
|
27
|
-
|
31
|
+
return mergeObjectsUsingReaderAst(field.selections, oldItem, newItem);
|
32
|
+
default: {
|
33
|
+
// Ensure we have covered all variants
|
34
|
+
let _: never = field;
|
35
|
+
_;
|
36
|
+
throw new Error('Unexpected case.');
|
28
37
|
}
|
29
|
-
|
30
|
-
return areEqualObjectsWithDeepComparison(oldItem, newItem);
|
31
38
|
}
|
32
|
-
|
33
|
-
return newItem === oldItem;
|
34
39
|
}
|
35
40
|
|
36
|
-
export function
|
41
|
+
export function mergeArraysUsingReaderAst(
|
42
|
+
field: ReaderScalarField | ReaderLinkedField,
|
37
43
|
oldItems: ReadonlyArray<unknown>,
|
38
|
-
newItems:
|
39
|
-
):
|
44
|
+
newItems: Array<unknown>,
|
45
|
+
): ReadonlyArray<unknown> {
|
40
46
|
if (newItems.length !== oldItems.length) {
|
41
|
-
return
|
47
|
+
return newItems;
|
42
48
|
}
|
43
49
|
|
50
|
+
let canRecycle = true;
|
44
51
|
for (let i = 0; i < newItems.length; i++) {
|
45
|
-
|
46
|
-
|
52
|
+
const mergedItem = mergeUsingReaderAst(field, oldItems[i], newItems[i]);
|
53
|
+
if (mergedItem !== oldItems[i]) {
|
54
|
+
canRecycle = false;
|
55
|
+
} else {
|
56
|
+
newItems[i] = mergedItem;
|
47
57
|
}
|
48
58
|
}
|
49
59
|
|
50
|
-
return
|
60
|
+
return canRecycle ? oldItems : newItems;
|
51
61
|
}
|
52
62
|
|
53
|
-
export function
|
63
|
+
export function mergeObjectsUsingReaderAst(
|
64
|
+
ast: ReaderAst<object>,
|
54
65
|
oldItemObject: object,
|
55
66
|
newItemObject: object,
|
56
|
-
):
|
57
|
-
|
58
|
-
const
|
67
|
+
): object {
|
68
|
+
let canRecycle = true;
|
69
|
+
for (const field of ast) {
|
70
|
+
switch (field.kind) {
|
71
|
+
case 'Scalar':
|
72
|
+
case 'Linked':
|
73
|
+
const key = field.alias ?? field.fieldName;
|
74
|
+
// @ts-expect-error
|
75
|
+
const oldValue = oldItemObject[key];
|
76
|
+
// @ts-expect-error
|
77
|
+
const newValue = newItemObject[key];
|
59
78
|
|
60
|
-
|
61
|
-
|
62
|
-
|
79
|
+
const mergedValue = mergeUsingReaderAst(field, oldValue, newValue);
|
80
|
+
if (mergedValue !== oldValue) {
|
81
|
+
canRecycle = false;
|
82
|
+
} else {
|
83
|
+
// @ts-expect-error
|
84
|
+
newItemObject[key] = mergedValue;
|
85
|
+
}
|
86
|
+
break;
|
87
|
+
case 'Resolver': {
|
88
|
+
const key = field.alias;
|
89
|
+
// @ts-expect-error
|
90
|
+
const oldValue = oldItemObject[key];
|
91
|
+
// @ts-expect-error
|
92
|
+
const newValue = newItemObject[key];
|
63
93
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
94
|
+
if (oldValue !== newValue) {
|
95
|
+
canRecycle = false;
|
96
|
+
}
|
97
|
+
break;
|
98
|
+
}
|
99
|
+
case 'ImperativelyLoadedField':
|
100
|
+
case 'LoadablySelectedField':
|
101
|
+
break;
|
102
|
+
default: {
|
103
|
+
// Ensure we have covered all variants
|
104
|
+
let _: never = field;
|
105
|
+
_;
|
106
|
+
throw new Error('Unexpected case.');
|
107
|
+
}
|
75
108
|
}
|
76
109
|
}
|
77
|
-
|
110
|
+
|
111
|
+
return canRecycle ? oldItemObject : newItemObject;
|
78
112
|
}
|