diff --git a/CHANGELOG.md b/CHANGELOG.md
index e651bccf..f98b16df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
# master
- fix remove-unused-fields command. https://github.com/zth/rescript-relay/pull/636
+- Fix `useRefetchableFragment` and `usePaginationFragment` to be compatible with `fromData`.
# 4.5.1
diff --git a/packages/rescript-relay/__tests__/Test_paginationInNode-tests.js b/packages/rescript-relay/__tests__/Test_paginationInNode-tests.js
index 4ac5e83c..6d4be552 100644
--- a/packages/rescript-relay/__tests__/Test_paginationInNode-tests.js
+++ b/packages/rescript-relay/__tests__/Test_paginationInNode-tests.js
@@ -4,7 +4,7 @@ const ReactTestUtils = require("react-dom/test-utils");
const React = require("react");
const queryMock = require("./queryMock");
-const { test_pagination } = require("./Test_paginationInNode.bs");
+const { test_pagination, test_pagination_from_data } = require("./Test_paginationInNode.bs");
describe("Pagination nested in node", () => {
test("paginating works", async () => {
@@ -180,4 +180,9 @@ describe("Pagination nested in node", () => {
await t.screen.findByText("User Second has 3 friends");
expect(t.screen.queryByText("User First has 2 friends")).toBeFalsy();
});
+
+ test("usePagination supports `fromData`", async () => {
+ t.render(test_pagination_from_data());
+ await t.screen.findByText("Test Data has 2 friends");
+ });
});
diff --git a/packages/rescript-relay/__tests__/Test_paginationInNode.res b/packages/rescript-relay/__tests__/Test_paginationInNode.res
index 6a469928..00188db2 100644
--- a/packages/rescript-relay/__tests__/Test_paginationInNode.res
+++ b/packages/rescript-relay/__tests__/Test_paginationInNode.res
@@ -113,6 +113,15 @@ module Test = {
}
}
+module FromDataPaginationComponent = {
+ @react.component
+ let make = (~user) => {
+ let {data} = Fragment.usePagination(user)
+ let friendCount = data.friendsConnection->Fragment.getConnectionNodes->Array.length
+
{React.string(`Test Data has ${friendCount->Int.toString} friends`)}
+ }
+}
+
@live
let test_pagination = () => {
let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=RelayEnv.fetchQuery)
@@ -126,3 +135,39 @@ let test_pagination = () => {
}
+
+@live
+let test_pagination_from_data = () => {
+ let environment = RescriptRelay_Test.createMockEnvironment()
+
+
+
+}
diff --git a/packages/rescript-relay/__tests__/Test_refetching-tests.js b/packages/rescript-relay/__tests__/Test_refetching-tests.js
index b3a00d83..9ebda74a 100644
--- a/packages/rescript-relay/__tests__/Test_refetching-tests.js
+++ b/packages/rescript-relay/__tests__/Test_refetching-tests.js
@@ -4,7 +4,7 @@ const React = require("react");
const queryMock = require("./queryMock");
const ReactTestUtils = require("react-dom/test-utils");
-const { test_refetching } = require("./Test_refetching.bs");
+const { test_refetching, test_refetchable_component } = require("./Test_refetching.bs");
describe("Fragment", () => {
test("refetching works", async () => {
@@ -70,4 +70,9 @@ describe("Fragment", () => {
await t.screen.findByText("First is online");
await t.screen.findByText("Friends: 10");
});
+
+ test("useRefetchable supports `fromData`", async () => {
+ t.render(test_refetchable_component());
+ await t.screen.findByText("Test Data has 3 friends");
+ });
});
diff --git a/packages/rescript-relay/__tests__/Test_refetching.res b/packages/rescript-relay/__tests__/Test_refetching.res
index d8da9d67..b97915e7 100644
--- a/packages/rescript-relay/__tests__/Test_refetching.res
+++ b/packages/rescript-relay/__tests__/Test_refetching.res
@@ -83,6 +83,18 @@ module Test = {
}
}
+module RefetchableComponent = {
+ @react.component
+ let make = (~user) => {
+ let (data, _refetch) = Fragment.useRefetchable(user)
+
+ {React.string(
+ `${data.firstName} has ${data.friendsConnection.totalCount->Int.toString} friends`,
+ )}
+
+ }
+}
+
@live
let test_refetching = () => {
let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=RelayEnv.fetchQuery)
@@ -96,3 +108,19 @@ let test_refetching = () => {
}
+
+@live
+let test_refetchable_component = () => {
+ let environment = RescriptRelay_Test.createMockEnvironment()
+
+
+
+}
diff --git a/packages/rescript-relay/src/RescriptRelay_Fragment.res b/packages/rescript-relay/src/RescriptRelay_Fragment.res
index a08743d6..142337e9 100644
--- a/packages/rescript-relay/src/RescriptRelay_Fragment.res
+++ b/packages/rescript-relay/src/RescriptRelay_Fragment.res
@@ -87,8 +87,35 @@ let internal_makeRefetchableFnOpts = (~fetchPolicy=?, ~onComplete=?, ()) => {
onComplete: ?(onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler),
}
+module InternalNoopDisposable = {
+ type t = {dispose: unit => unit}
+ external toOpaqueDisposable: t => Disposable.t = "%identity"
+ let noop = {dispose: () => ()}->toOpaqueDisposable
+}
+
+let internal_noopRefetch = (
+ ~variables as _,
+ ~fetchPolicy as _=?,
+ ~onComplete=?,
+) => {
+ switch onComplete {
+ | None => ()
+ | Some(complete) => complete(None)
+ }
+ InternalNoopDisposable.noop
+}
+
type paginationLoadMoreOptions = {onComplete?: Nullable.t => unit}
type paginationLoadMoreFn = (~count: int, ~onComplete: option => unit=?) => Disposable.t
+
+let internal_noopLoadMore = (~count as _, ~onComplete=?) => {
+ switch onComplete {
+ | None => ()
+ | Some(complete) => complete(None)
+ }
+ InternalNoopDisposable.noop
+}
+
type paginationFragmentReturnRaw<'fragment, 'refetchVariables> = {
data: 'fragment,
loadNext: (int, paginationLoadMoreOptions) => Disposable.t,
@@ -127,40 +154,53 @@ let usePaginationFragment = (
~convertFragment: 'fragment => 'fragment,
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
) => {
- let p = usePaginationFragment_(node, fRef)
- let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, p.data)
- {
- data,
- loadNext: React.useMemo1(() =>
- (~count, ~onComplete=?) => {
- p.loadNext(
- count,
- {onComplete: ?(onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler)},
- )
- }
- , [p.loadNext]),
- loadPrevious: React.useMemo1(() =>
- (~count, ~onComplete=?) => {
- p.loadPrevious(
- count,
- {onComplete: ?(onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler)},
- )
- }
- , [p.loadPrevious]),
- hasNext: p.hasNext,
- hasPrevious: p.hasPrevious,
- isLoadingNext: p.isLoadingNext,
- isLoadingPrevious: p.isLoadingPrevious,
- refetch: React.useMemo1(() =>
- (~variables, ~fetchPolicy=?, ~onComplete=?) => {
- p.refetch(
- RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw(
- variables->convertRefetchVariables,
- ),
- internal_makeRefetchableFnOpts(~onComplete?, ~fetchPolicy?, ()),
- )
- }
- , [p.refetch]),
+ switch RescriptRelay_TestFragmentRef.getDataForNode(node, fRef) {
+ | Some(data) => {
+ data,
+ loadNext: internal_noopLoadMore,
+ loadPrevious: internal_noopLoadMore,
+ hasNext: false,
+ hasPrevious: false,
+ isLoadingNext: false,
+ isLoadingPrevious: false,
+ refetch: internal_noopRefetch,
+ }
+ | None =>
+ let p = usePaginationFragment_(node, fRef)
+ let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, p.data)
+ {
+ data,
+ loadNext: React.useMemo1(() =>
+ (~count, ~onComplete=?) => {
+ p.loadNext(
+ count,
+ {onComplete: ?(onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler)},
+ )
+ }
+ , [p.loadNext]),
+ loadPrevious: React.useMemo1(() =>
+ (~count, ~onComplete=?) => {
+ p.loadPrevious(
+ count,
+ {onComplete: ?(onComplete->RescriptRelay_Internal.internal_nullableToOptionalExnHandler)},
+ )
+ }
+ , [p.loadPrevious]),
+ hasNext: p.hasNext,
+ hasPrevious: p.hasPrevious,
+ isLoadingNext: p.isLoadingNext,
+ isLoadingPrevious: p.isLoadingPrevious,
+ refetch: React.useMemo1(() =>
+ (~variables, ~fetchPolicy=?, ~onComplete=?) => {
+ p.refetch(
+ RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw(
+ variables->convertRefetchVariables,
+ ),
+ internal_makeRefetchableFnOpts(~onComplete?, ~fetchPolicy?, ()),
+ )
+ }
+ , [p.refetch]),
+ }
}
}
@@ -267,22 +307,26 @@ let useRefetchableFragment = (
~convertRefetchVariables: 'refetchVariables => 'refetchVariables,
~fRef,
) => {
- let (fragmentData, refetchFn) = useRefetchableFragment_(node, fRef)
- let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, fragmentData)
- (
- data,
- React.useMemo1(
- () =>
- (~variables: 'refetchVariables, ~fetchPolicy=?, ~onComplete=?) =>
- refetchFn(
- RescriptRelay_Internal.internal_removeUndefinedAndConvertNullsRaw(
- variables->convertRefetchVariables,
- )->RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw,
- internal_makeRefetchableFnOpts(~fetchPolicy?, ~onComplete?, ()),
- ),
- [refetchFn],
- ),
- )
+ switch RescriptRelay_TestFragmentRef.getDataForNode(node, fRef) {
+ | Some(data) => (data, internal_noopRefetch)
+ | None =>
+ let (fragmentData, refetchFn) = useRefetchableFragment_(node, fRef)
+ let data = RescriptRelay_Internal.internal_useConvertedValue(convertFragment, fragmentData)
+ (
+ data,
+ React.useMemo1(
+ () =>
+ (~variables: 'refetchVariables, ~fetchPolicy=?, ~onComplete=?) =>
+ refetchFn(
+ RescriptRelay_Internal.internal_removeUndefinedAndConvertNullsRaw(
+ variables->convertRefetchVariables,
+ )->RescriptRelay_Internal.internal_cleanObjectFromUndefinedRaw,
+ internal_makeRefetchableFnOpts(~fetchPolicy?, ~onComplete?, ()),
+ ),
+ [refetchFn],
+ ),
+ )
+ }
}
@module("relay-runtime/experimental")