From 2a6cb0fe86dcd2c3f8ea2542386adf559eb6c13c Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 14 Dec 2024 21:45:11 +0100 Subject: [PATCH] Relay 18.2 (#542) * up packages, and pull latest compiler * bind waitForFragmentData * 3.1.0 * add experimental non React mode to the PPX * fix inclusion * changelog * up docs --- CHANGELOG.md | 10 + packages/relay | 2 +- .../__tests__/Test_nonReact-tests.js | 25 +++ .../__tests__/Test_nonReact.res | 35 +++ .../__tests__/Test_requiredFieldLogger.res | 2 +- .../TestAliasedFragmentsQuery_graphql.res | 38 ++-- .../TestCodesplitQuery_graphql.res | 76 ++++--- ...estFragmentRequiredPlural_user_graphql.res | 3 +- .../TestFragmentRequired_user_graphql.res | 3 +- .../TestNonReactQuery_graphql.res | 206 ++++++++++++++++++ .../TestNonReact_user_graphql.res | 83 +++++++ .../TestRelayResolversAllQuery_graphql.res | 3 +- .../TestRequiredFieldLoggerQuery_graphql.res | 3 +- .../__generated__/UserAvatar_user_graphql.res | 19 +- packages/rescript-relay/package.json | 10 +- packages/rescript-relay/relay.config.js | 6 - .../bin/RescriptRelayPpxApp.ml | 5 + .../rescript-relay-ppx/library/Fragment.ml | 39 +++- .../rescript-relay-ppx/library/Mutation.ml | 73 ++++--- .../library/NonReactUtils.ml | 1 + .../rescript-relay-ppx/library/Query.ml | 84 +++---- .../library/RescriptRelayPpxLibrary.ml | 1 + .../library/UncurriedUtils.ml | 14 +- packages/rescript-relay/src/RescriptRelay.res | 19 +- .../rescript-relay/src/RescriptRelay.resi | 15 +- .../src/RescriptRelay_Fragment.res | 17 ++ .../src/RescriptRelay_Fragment.resi | 7 + packages/rescript-relay/yarn.lock | 36 ++- .../docs/getting-started.md | 4 +- .../docs/relay-resolvers.md | 8 +- .../docs/using-fragments.md | 2 +- 31 files changed, 668 insertions(+), 181 deletions(-) create mode 100644 packages/rescript-relay/__tests__/Test_nonReact-tests.js create mode 100644 packages/rescript-relay/__tests__/Test_nonReact.res create mode 100644 packages/rescript-relay/__tests__/__generated__/TestNonReactQuery_graphql.res create mode 100644 packages/rescript-relay/__tests__/__generated__/TestNonReact_user_graphql.res create mode 100644 packages/rescript-relay/rescript-relay-ppx/library/NonReactUtils.ml diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a36358..21af31cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # master +# 3.1.0 + +This brings the Relay version to `18.2.0`. + +If you have enabled the feature flags in `relay.config.js` for aliased fragments or Relay resolvers you'll need to remove them from the config file as they are now on by default, and not removing them will cause the compiler to fail with a non super helpful error message. + +- **Upgrade versions**: `react-relay` and `relay-runtime` to `18.2.0`. +- Add support for `Fragment.waitForFragmentData`, a new API in Relay 18.2 that lets you wait for fragment data outside of React. +- Experimental: Add a "non React" mode to the PPX, which makes sure only APIs that don't rely on React directly are exposed. This is intended to be a way to simplify using RescriptRelay without React. Activate by passing `-non-react` to the PPX, like `"ppx-flags": [["rescript-relay/ppx", "-non-react"]]`. + # 3.0.1 - Add `Environment.findAllConnectionIds` for finding all IDs of all connection instances for a specific connection, regardless of what configs that connection has been fetched (and cached) with. diff --git a/packages/relay b/packages/relay index 1b2d5616..00960d5f 160000 --- a/packages/relay +++ b/packages/relay @@ -1 +1 @@ -Subproject commit 1b2d5616cdbccf3d6244806888070f3866d31e97 +Subproject commit 00960d5f9e8e67e2dc304554ac5bf75a878972a6 diff --git a/packages/rescript-relay/__tests__/Test_nonReact-tests.js b/packages/rescript-relay/__tests__/Test_nonReact-tests.js new file mode 100644 index 00000000..683b828f --- /dev/null +++ b/packages/rescript-relay/__tests__/Test_nonReact-tests.js @@ -0,0 +1,25 @@ +require("@testing-library/jest-dom/extend-expect"); +const queryMock = require("./queryMock"); + +const { test_nonReact } = require("./Test_nonReact.bs"); + +describe("Fragment", () => { + test("waitForFragmentData works", async () => { + queryMock.mockQuery({ + name: "TestNonReactQuery", + data: { + loggedInUser: { + id: "user-1", + firstName: "First", + onlineStatus: "Online", + }, + }, + }); + + const res = await test_nonReact(); + expect(res.waitForFragmentData).toEqual({ + firstName: "First", + onlineStatus: "Online", + }); + }); +}); diff --git a/packages/rescript-relay/__tests__/Test_nonReact.res b/packages/rescript-relay/__tests__/Test_nonReact.res new file mode 100644 index 00000000..4ff10703 --- /dev/null +++ b/packages/rescript-relay/__tests__/Test_nonReact.res @@ -0,0 +1,35 @@ +module Query = %relay(` + query TestNonReactQuery { + loggedInUser { + firstName + ...TestNonReact_user + } + } +`) + +module Fragment = %relay(` + fragment TestNonReact_user on User { + firstName + onlineStatus + } +`) + +@live +let test_nonReact = async () => { + let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=RelayEnv.fetchQuery) + + let environment = RescriptRelay.Environment.make( + ~network, + ~store=RescriptRelay.Store.make(~source=RescriptRelay.RecordSource.make()), + ) + + let query = await Query.fetchPromised(~environment, ~variables=()) + let fragmentData = await Fragment.waitForFragmentData( + ~environment, + query.loggedInUser.fragmentRefs, + ) + + { + "waitForFragmentData": fragmentData, + } +} diff --git a/packages/rescript-relay/__tests__/Test_requiredFieldLogger.res b/packages/rescript-relay/__tests__/Test_requiredFieldLogger.res index 272c0635..cbce1be5 100644 --- a/packages/rescript-relay/__tests__/Test_requiredFieldLogger.res +++ b/packages/rescript-relay/__tests__/Test_requiredFieldLogger.res @@ -13,7 +13,7 @@ module Logger = { let getLoggedArg = () => loggedArg.contents - let expectedArg: RescriptRelay.RelayFieldLogger.arg = MissingFieldLog({ + let expectedArg: RescriptRelay.RelayFieldLogger.arg = MissingRequiredFieldLog({ owner: "TestRequiredFieldLoggerQuery", fieldPath: "loggedInUser.firstName", }) diff --git a/packages/rescript-relay/__tests__/__generated__/TestAliasedFragmentsQuery_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestAliasedFragmentsQuery_graphql.res index 19c20560..7753980a 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestAliasedFragmentsQuery_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestAliasedFragmentsQuery_graphql.res @@ -116,14 +116,19 @@ return { "selections": [ { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "TestAliasedFragments_userFirstName" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "TestAliasedFragments_userFirstName" + } + ], + "type": "User", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "TestAliasedFragments_userFirstName", - "type": "User", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "TestAliasedFragments_userFirstName" }, { "condition": "skipThing", @@ -132,14 +137,19 @@ return { "selections": [ { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "TestAliasedFragments_userLastName" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "TestAliasedFragments_userLastName" + } + ], + "type": "User", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "TestAliasedFragments_userLastName", - "type": "User", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "TestAliasedFragments_userLastName" } ] } diff --git a/packages/rescript-relay/__tests__/__generated__/TestCodesplitQuery_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestCodesplitQuery_graphql.res index 8cbe696e..1c5ec0a5 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestCodesplitQuery_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestCodesplitQuery_graphql.res @@ -145,26 +145,36 @@ v2 = { }, v3 = { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "UserAvatar_user" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "UserAvatar_user" + } + ], + "type": "User", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "UserAvatar_user", - "type": "User", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "UserAvatar_user" }, v4 = [ { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "RichContent_content" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "RichContent_content" + } + ], + "type": "RichContent", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "RichContent_content", - "type": "RichContent", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "RichContent_content" } ], v5 = [ @@ -231,14 +241,19 @@ return { (v2/*: any*/), { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "HasNameComponent_hasName" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "HasNameComponent_hasName" + } + ], + "type": "HasName", + "abstractKey": "__isHasName" }, - "kind": "AliasedFragmentSpread", - "name": "HasNameComponent_hasName", - "type": "HasName", - "abstractKey": "__isHasName" + "kind": "AliasedInlineFragmentSpread", + "name": "HasNameComponent_hasName" }, { "kind": "InlineFragment", @@ -299,14 +314,19 @@ return { "selections": [ { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "GroupAvatar_group" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "GroupAvatar_group" + } + ], + "type": "Group", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "GroupAvatar_group", - "type": "Group", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "GroupAvatar_group" } ], "type": "Group", diff --git a/packages/rescript-relay/__tests__/__generated__/TestFragmentRequiredPlural_user_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestFragmentRequiredPlural_user_graphql.res index 4e3b1ca3..08a0e0a3 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestFragmentRequiredPlural_user_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestFragmentRequiredPlural_user_graphql.res @@ -73,8 +73,7 @@ let node: operationType = %raw(json` { "name": "onlineStatus", "storageKey": null }, - "action": "NONE", - "path": "onlineStatus" + "action": "NONE" } ], "type": "User", diff --git a/packages/rescript-relay/__tests__/__generated__/TestFragmentRequired_user_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestFragmentRequired_user_graphql.res index 1d128d3a..0be79fa7 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestFragmentRequired_user_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestFragmentRequired_user_graphql.res @@ -71,8 +71,7 @@ let node: operationType = %raw(json` { "name": "onlineStatus", "storageKey": null }, - "action": "NONE", - "path": "onlineStatus" + "action": "NONE" } ], "type": "User", diff --git a/packages/rescript-relay/__tests__/__generated__/TestNonReactQuery_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestNonReactQuery_graphql.res new file mode 100644 index 00000000..c6d3b39a --- /dev/null +++ b/packages/rescript-relay/__tests__/__generated__/TestNonReactQuery_graphql.res @@ -0,0 +1,206 @@ +/* @sourceLoc Test_nonReact.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type rec response_loggedInUser = { + firstName: string, + fragmentRefs: RescriptRelay.fragmentRefs<[ | #TestNonReact_user]>, + } + type response = { + loggedInUser: response_loggedInUser, + } + @live + type rawResponse = response + @live + type variables = unit + @live + type refetchVariables = unit + @live let makeRefetchVariables = () => () +} + + +type queryRef + +module Internal = { + @live + let variablesConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let variablesConverterMap = () + @live + let convertVariables = v => v->RescriptRelay.convertObj( + variablesConverter, + variablesConverterMap, + Js.undefined + ) + @live + type wrapResponseRaw + @live + let wrapResponseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"loggedInUser":{"f":""}}}` + ) + @live + let wrapResponseConverterMap = () + @live + let convertWrapResponse = v => v->RescriptRelay.convertObj( + wrapResponseConverter, + wrapResponseConverterMap, + Js.null + ) + @live + type responseRaw + @live + let responseConverter: Js.Dict.t>> = %raw( + json`{"__root":{"loggedInUser":{"f":""}}}` + ) + @live + let responseConverterMap = () + @live + let convertResponse = v => v->RescriptRelay.convertObj( + responseConverter, + responseConverterMap, + Js.undefined + ) + type wrapRawResponseRaw = wrapResponseRaw + @live + let convertWrapRawResponse = convertWrapResponse + type rawResponseRaw = responseRaw + @live + let convertRawResponse = convertResponse + type rawPreloadToken<'response> = {source: Js.Nullable.t>} + external tokenToRaw: queryRef => rawPreloadToken = "%identity" +} +module Utils = { + @@warning("-33") + open Types +} + +type relayOperationNode +type operationType = RescriptRelay.queryNode + + +let node: operationType = %raw(json` (function(){ +var v0 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "firstName", + "storageKey": null +}; +return { + "fragment": { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "TestNonReactQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "args": null, + "kind": "FragmentSpread", + "name": "TestNonReact_user" + } + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": [], + "kind": "Operation", + "name": "TestNonReactQuery", + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "User", + "kind": "LinkedField", + "name": "loggedInUser", + "plural": false, + "selections": [ + (v0/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "onlineStatus", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "d5f8ad416242fa091016dc4827700a34", + "id": null, + "metadata": {}, + "name": "TestNonReactQuery", + "operationKind": "query", + "text": "query TestNonReactQuery {\n loggedInUser {\n firstName\n ...TestNonReact_user\n id\n }\n}\n\nfragment TestNonReact_user on User {\n firstName\n onlineStatus\n}\n" + } +}; +})() `) + +@live let load: ( + ~environment: RescriptRelay.Environment.t, + ~variables: Types.variables, + ~fetchPolicy: RescriptRelay.fetchPolicy=?, + ~fetchKey: string=?, + ~networkCacheConfig: RescriptRelay.cacheConfig=?, +) => queryRef = ( + ~environment, + ~variables, + ~fetchPolicy=?, + ~fetchKey=?, + ~networkCacheConfig=?, +) => + RescriptRelay.loadQuery( + environment, + node, + variables->Internal.convertVariables, + { + fetchKey, + fetchPolicy, + networkCacheConfig, + }, + ) + +@live +let queryRefToObservable = token => { + let raw = token->Internal.tokenToRaw + raw.source->Js.Nullable.toOption +} + +@live +let queryRefToPromise = token => { + Js.Promise.make((~resolve, ~reject as _) => { + switch token->queryRefToObservable { + | None => resolve(Error()) + | Some(o) => + open RescriptRelay.Observable + let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok()))) + } + }) +} diff --git a/packages/rescript-relay/__tests__/__generated__/TestNonReact_user_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestNonReact_user_graphql.res new file mode 100644 index 00000000..16a808d4 --- /dev/null +++ b/packages/rescript-relay/__tests__/__generated__/TestNonReact_user_graphql.res @@ -0,0 +1,83 @@ +/* @sourceLoc Test_nonReact.res */ +/* @generated */ +%%raw("/* @generated */") +module Types = { + @@warning("-30") + + type fragment = { + firstName: string, + onlineStatus: option, + } +} + +module Internal = { + @live + type fragmentRaw + @live + let fragmentConverter: Js.Dict.t>> = %raw( + json`{}` + ) + @live + let fragmentConverterMap = () + @live + let convertFragment = v => v->RescriptRelay.convertObj( + fragmentConverter, + fragmentConverterMap, + Js.undefined + ) +} + +type t +type fragmentRef +external getFragmentRef: + RescriptRelay.fragmentRefs<[> | #TestNonReact_user]> => fragmentRef = "%identity" + +module Utils = { + @@warning("-33") + open Types + @live + external onlineStatus_toString: RelaySchemaAssets_graphql.enum_OnlineStatus => string = "%identity" + @live + external onlineStatus_input_toString: RelaySchemaAssets_graphql.enum_OnlineStatus_input => string = "%identity" + @live + let onlineStatus_decode = (enum: RelaySchemaAssets_graphql.enum_OnlineStatus): option => { + switch enum { + | FutureAddedValue(_) => None + | valid => Some(Obj.magic(valid)) + } + } + @live + let onlineStatus_fromString = (str: string): option => { + onlineStatus_decode(Obj.magic(str)) + } +} + +type relayOperationNode +type operationType = RescriptRelay.fragmentNode + + +let node: operationType = %raw(json` { + "argumentDefinitions": [], + "kind": "Fragment", + "metadata": null, + "name": "TestNonReact_user", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "firstName", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "onlineStatus", + "storageKey": null + } + ], + "type": "User", + "abstractKey": null +} `) + diff --git a/packages/rescript-relay/__tests__/__generated__/TestRelayResolversAllQuery_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestRelayResolversAllQuery_graphql.res index 9fe238cc..7eb1dfa4 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestRelayResolversAllQuery_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestRelayResolversAllQuery_graphql.res @@ -248,8 +248,7 @@ return { "storageKey": null } }, - "action": "NONE", - "path": "localUser.meta" + "action": "NONE" }, { "alias": null, diff --git a/packages/rescript-relay/__tests__/__generated__/TestRequiredFieldLoggerQuery_graphql.res b/packages/rescript-relay/__tests__/__generated__/TestRequiredFieldLoggerQuery_graphql.res index 7b5d5691..4bc140fc 100644 --- a/packages/rescript-relay/__tests__/__generated__/TestRequiredFieldLoggerQuery_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/TestRequiredFieldLoggerQuery_graphql.res @@ -107,8 +107,7 @@ return { { "kind": "RequiredField", "field": (v0/*: any*/), - "action": "LOG", - "path": "loggedInUser.firstName" + "action": "LOG" } ], "storageKey": null diff --git a/packages/rescript-relay/__tests__/__generated__/UserAvatar_user_graphql.res b/packages/rescript-relay/__tests__/__generated__/UserAvatar_user_graphql.res index d57bd17b..c044f3a1 100644 --- a/packages/rescript-relay/__tests__/__generated__/UserAvatar_user_graphql.res +++ b/packages/rescript-relay/__tests__/__generated__/UserAvatar_user_graphql.res @@ -63,14 +63,19 @@ let node: operationType = %raw(json` { }, { "fragment": { - "args": null, - "kind": "FragmentSpread", - "name": "UserName_user" + "kind": "InlineFragment", + "selections": [ + { + "args": null, + "kind": "FragmentSpread", + "name": "UserName_user" + } + ], + "type": "User", + "abstractKey": null }, - "kind": "AliasedFragmentSpread", - "name": "UserName_user", - "type": "User", - "abstractKey": null + "kind": "AliasedInlineFragmentSpread", + "name": "UserName_user" } ], "type": "User", diff --git a/packages/rescript-relay/package.json b/packages/rescript-relay/package.json index d725fbb8..8d101619 100644 --- a/packages/rescript-relay/package.json +++ b/packages/rescript-relay/package.json @@ -1,6 +1,6 @@ { "name": "rescript-relay", - "version": "3.0.1", + "version": "3.1.0", "main": "src/RescriptRelay.res", "license": "MIT", "author": "Gabriel Nordeborn", @@ -49,14 +49,14 @@ "node-fetch": "^2.6.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-relay": "17.0.0", - "relay-runtime": "17.0.0", + "react-relay": "18.2.0", + "relay-runtime": "18.2.0", "rescript": "11.1.1" }, "peerDependencies": { "@rescript/react": ">=0.13.0", - "react-relay": "17.0.0", - "relay-runtime": "17.0.0", + "react-relay": "18.2.0", + "relay-runtime": "18.2.0", "rescript": "^11.0.0" }, "dependencies": { diff --git a/packages/rescript-relay/relay.config.js b/packages/rescript-relay/relay.config.js index c3d9e205..9d91efae 100644 --- a/packages/rescript-relay/relay.config.js +++ b/packages/rescript-relay/relay.config.js @@ -13,12 +13,6 @@ module.exports = { JSON: "Js.Json.t", Number: "TestsUtils.Number", }, - featureFlags: { - enable_relay_resolver_transform: true, - enable_fragment_aliases: { - kind: "enabled", - }, - }, persistConfig: PERSISTING ? { file: "./persistedQueries.json", diff --git a/packages/rescript-relay/rescript-relay-ppx/bin/RescriptRelayPpxApp.ml b/packages/rescript-relay/rescript-relay-ppx/bin/RescriptRelayPpxApp.ml index 94650712..c2ed3e75 100755 --- a/packages/rescript-relay/rescript-relay-ppx/bin/RescriptRelayPpxApp.ml +++ b/packages/rescript-relay/rescript-relay-ppx/bin/RescriptRelayPpxApp.ml @@ -5,4 +5,9 @@ let () = (Arg.Unit (fun () -> RescriptRelayPpxLibrary.UncurriedUtils.enabled := true)) ~doc:"Run in uncurried mode" +let () = + Driver.add_arg "-non-react" + (Arg.Unit (fun () -> RescriptRelayPpxLibrary.NonReactUtils.enabled := true)) + ~doc:"Run non-React mode" + let _ = Driver.run_as_ppx_rewriter () diff --git a/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml b/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml index 3090f32d..13c12bad 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml @@ -23,17 +23,28 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo [%t typeFromGeneratedModule ["Types"; "fragment"]] = [%e valFromGeneratedModule ["Internal"; "convertFragment"]]]; ]; - (match hasAutocodesplitDirective with - | true -> + (match (!NonReactUtils.enabled, hasAutocodesplitDirective) with + | true, _ -> [] + | false, true -> [ [%stri module CodesplitComponents = [%m moduleIdentFromGeneratedModule ["CodesplitComponents"]]]; ] - | false -> []); - (match hasInlineDirective with - | false -> + | false, false -> []); + [ + [%stri + let waitForFragmentData ~environment fRef = + RescriptRelay_Fragment.waitForFragmentData ~environment + ~convertFragment + ~fRef: + (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) + ~node:[%e valFromGeneratedModule ["node"]]]; + ]; + (match (!NonReactUtils.enabled, hasInlineDirective) with + | true, _ -> [] + | false, false -> [ [%stri let use fRef : @@ -55,6 +66,11 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo |. [%e valFromGeneratedModule ["getFragmentRef"]]) | None -> None) ~node:[%e valFromGeneratedModule ["node"]]]; + ] + | false, true -> []); + (match hasInlineDirective with + | false -> + [ (if isPlural then [%stri let readResolverFragment fRef : @@ -85,8 +101,9 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo ~node:[%e valFromGeneratedModule ["node"]]]); ] | true -> []); - (match hasInlineDirective with - | true -> + (match (!NonReactUtils.enabled, hasInlineDirective) with + | true, _ -> [] + | false, true -> [ [%stri let readInline fRef : @@ -96,10 +113,10 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) ~node:[%e valFromGeneratedModule ["node"]]]; ] - | false -> []); - (match refetchableQueryName with - | None -> [] - | Some refetchableQueryName -> + | false, false -> []); + (match (!NonReactUtils.enabled, refetchableQueryName) with + | true, _ | false, None -> [] + | false, Some refetchableQueryName -> let typeFromRefetchableModule = makeTypeAccessor ~loc ~moduleName:refetchableQueryName in diff --git a/packages/rescript-relay/rescript-relay-ppx/library/Mutation.ml b/packages/rescript-relay/rescript-relay-ppx/library/Mutation.ml index 01e6931a..ef69f805 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Mutation.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Mutation.ml @@ -9,39 +9,44 @@ let make ~loc ~moduleName = (Pmod_structure (List.concat [ - [ - [%stri [@@@ocaml.warning "-32-34-60"]]; - [%stri include [%m moduleIdentFromGeneratedModule ["Utils"]]]; - [%stri module Operation = [%m moduleIdentFromGeneratedModule []]]; - [%stri - module Types = [%m moduleIdentFromGeneratedModule ["Types"]]]; - [%stri - let convertVariables : - [%t typeFromGeneratedModule ["Types"; "variables"]] -> - [%t typeFromGeneratedModule ["Types"; "variables"]] = - [%e valFromGeneratedModule ["Internal"; "convertVariables"]]]; - [%stri - let convertResponse : - [%t typeFromGeneratedModule ["Types"; "response"]] -> - [%t typeFromGeneratedModule ["Types"; "response"]] = - [%e valFromGeneratedModule ["Internal"; "convertResponse"]]]; - [%stri - let convertWrapRawResponse : - [%t typeFromGeneratedModule ["Types"; "rawResponse"]] -> - [%t typeFromGeneratedModule ["Types"; "rawResponse"]] = - [%e - valFromGeneratedModule - ["Internal"; "convertWrapRawResponse"]]]; - [%stri - let commitMutation = - RescriptRelay_Mutation.commitMutation ~convertVariables - ~convertResponse ~convertWrapRawResponse - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let use = - RescriptRelay_Mutation.useMutation ~convertVariables - ~convertResponse ~convertWrapRawResponse - ~node:[%e valFromGeneratedModule ["node"]]]; - ]; + ([ + [%stri [@@@ocaml.warning "-32-34-60"]]; + [%stri include [%m moduleIdentFromGeneratedModule ["Utils"]]]; + [%stri module Operation = [%m moduleIdentFromGeneratedModule []]]; + [%stri + module Types = [%m moduleIdentFromGeneratedModule ["Types"]]]; + [%stri + let convertVariables : + [%t typeFromGeneratedModule ["Types"; "variables"]] -> + [%t typeFromGeneratedModule ["Types"; "variables"]] = + [%e valFromGeneratedModule ["Internal"; "convertVariables"]]]; + [%stri + let convertResponse : + [%t typeFromGeneratedModule ["Types"; "response"]] -> + [%t typeFromGeneratedModule ["Types"; "response"]] = + [%e valFromGeneratedModule ["Internal"; "convertResponse"]]]; + [%stri + let convertWrapRawResponse : + [%t typeFromGeneratedModule ["Types"; "rawResponse"]] -> + [%t typeFromGeneratedModule ["Types"; "rawResponse"]] = + [%e + valFromGeneratedModule + ["Internal"; "convertWrapRawResponse"]]]; + [%stri + let commitMutation = + RescriptRelay_Mutation.commitMutation ~convertVariables + ~convertResponse ~convertWrapRawResponse + ~node:[%e valFromGeneratedModule ["node"]]]; + ] + @ + if not !NonReactUtils.enabled then + [ + [%stri + let use = + RescriptRelay_Mutation.useMutation ~convertVariables + ~convertResponse ~convertWrapRawResponse + ~node:[%e valFromGeneratedModule ["node"]]]; + ] + else []); ] |> List.map UncurriedUtils.mapStructureItem)) diff --git a/packages/rescript-relay/rescript-relay-ppx/library/NonReactUtils.ml b/packages/rescript-relay/rescript-relay-ppx/library/NonReactUtils.ml new file mode 100644 index 00000000..40925dc6 --- /dev/null +++ b/packages/rescript-relay/rescript-relay-ppx/library/NonReactUtils.ml @@ -0,0 +1 @@ +let enabled = ref false diff --git a/packages/rescript-relay/rescript-relay-ppx/library/Query.ml b/packages/rescript-relay/rescript-relay-ppx/library/Query.ml index 43819151..d204ac82 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Query.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Query.ml @@ -40,50 +40,58 @@ let make ~loc ~moduleName ~hasRawResponseType ~hasAutocodesplitDirective = external mkQueryRef : [%t typeFromGeneratedModule ["queryRef"]] -> [%t typeFromGeneratedModule ["queryRef"]] = "%identity"]; - [%stri - let use = - RescriptRelay_Query.useQuery ~convertVariables - ~convertResponse - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let useLoader = - RescriptRelay_Query.useLoader ~convertVariables - ~mkQueryRef:mkQueryRefOpt - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let usePreloaded = - RescriptRelay_Query.usePreloaded ~convertResponse ~mkQueryRef - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let fetch = - RescriptRelay_Query.fetch ~convertResponse ~convertVariables - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let fetchPromised = - RescriptRelay_Query.fetchPromised ~convertResponse - ~convertVariables - ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let retain = - RescriptRelay_Query.retain ~convertVariables - ~node:[%e valFromGeneratedModule ["node"]]]; - (match hasRawResponseType with - | true -> + ] + @ (if not !NonReactUtils.enabled then + [ + [%stri + let use = + RescriptRelay_Query.useQuery ~convertVariables + ~convertResponse + ~node:[%e valFromGeneratedModule ["node"]]]; + [%stri + let useLoader = + RescriptRelay_Query.useLoader ~convertVariables + ~mkQueryRef:mkQueryRefOpt + ~node:[%e valFromGeneratedModule ["node"]]]; + [%stri + let usePreloaded = + RescriptRelay_Query.usePreloaded ~convertResponse + ~mkQueryRef + ~node:[%e valFromGeneratedModule ["node"]]]; + ] + else []) + @ [ + [%stri + let fetch = + RescriptRelay_Query.fetch ~convertResponse ~convertVariables + ~node:[%e valFromGeneratedModule ["node"]]]; + [%stri + let fetchPromised = + RescriptRelay_Query.fetchPromised ~convertResponse + ~convertVariables + ~node:[%e valFromGeneratedModule ["node"]]]; [%stri - let commitLocalPayload = - RescriptRelay_Query.commitLocalPayload ~convertVariables - ~convertWrapRawResponse - ~node:[%e valFromGeneratedModule ["node"]]] - | false -> [%stri ()]); - ]; - (match hasAutocodesplitDirective with - | true -> + let retain = + RescriptRelay_Query.retain ~convertVariables + ~node:[%e valFromGeneratedModule ["node"]]]; + (match hasRawResponseType with + | true -> + [%stri + let commitLocalPayload = + RescriptRelay_Query.commitLocalPayload ~convertVariables + ~convertWrapRawResponse + ~node:[%e valFromGeneratedModule ["node"]]] + | false -> [%stri ()]); + ]; + (match (!NonReactUtils.enabled, hasAutocodesplitDirective) with + | true, _ -> [] + | false, true -> [ [%stri module CodesplitComponents = [%m moduleIdentFromGeneratedModule ["CodesplitComponents"]]]; ] - | false -> []); + | false, false -> []); ] |> List.map UncurriedUtils.mapStructureItem)) diff --git a/packages/rescript-relay/rescript-relay-ppx/library/RescriptRelayPpxLibrary.ml b/packages/rescript-relay/rescript-relay-ppx/library/RescriptRelayPpxLibrary.ml index 3c732002..86b53e60 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/RescriptRelayPpxLibrary.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/RescriptRelayPpxLibrary.ml @@ -2,6 +2,7 @@ open Ppxlib open Util module Util = Util module UncurriedUtils = UncurriedUtils +module NonReactUtils = NonReactUtils let endsWithRegexp = Str.regexp ".*Resolver$" let commonExtension = Extension.declare "relay" Extension.Context.module_expr diff --git a/packages/rescript-relay/rescript-relay-ppx/library/UncurriedUtils.ml b/packages/rescript-relay/rescript-relay-ppx/library/UncurriedUtils.ml index 0b30d49e..e18c6079 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/UncurriedUtils.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/UncurriedUtils.ml @@ -41,6 +41,11 @@ let uncurriedType ~loc ~arity tArg = open Parsetree open Ast_mapper +let rec findArity ?(arity = 0) exp = + match exp.Parsetree.pexp_desc with + | Pexp_fun (_, _, _, nextExpr) -> findArity ~arity:(arity + 1) nextExpr + | _ -> arity + let wrapAsUncurriedFn ~arity item = match item.pstr_desc with | Pstr_value (a1, [({pvb_expr = {pexp_desc = Pexp_fun _} as fn} as outerV)]) @@ -53,8 +58,8 @@ let wrapAsUncurriedFn ~arity item = [ { outerV with - (* TODO: Should we care about actually figuring out the arity? *) - pvb_expr = uncurriedFun ~loc:outerV.pvb_loc ~arity fn; + pvb_expr = + uncurriedFun ~loc:outerV.pvb_loc ~arity:(findArity fn) fn; }; ] ); } @@ -98,8 +103,9 @@ let uncurriedMapper = [ { outerV with - (* TODO: Should we care about actually figuring out the arity? *) - pvb_expr = uncurriedFun ~loc:outerV.pvb_loc ~arity:1 fn; + pvb_expr = + uncurriedFun ~loc:outerV.pvb_loc ~arity:(findArity fn) + fn; }; ] ); } diff --git a/packages/rescript-relay/src/RescriptRelay.res b/packages/rescript-relay/src/RescriptRelay.res index c87d62da..64302d5c 100644 --- a/packages/rescript-relay/src/RescriptRelay.res +++ b/packages/rescript-relay/src/RescriptRelay.res @@ -643,9 +643,9 @@ module Store = { @module @new external makeLiveStoreCjs: (RecordSource.t, storeConfig) => t = - "relay-runtime/lib/store/experimental-live-resolvers/LiveResolverStore" + "relay-runtime/lib/store/live-resolvers/LiveResolverStore" - @module("relay-runtime/lib/store/experimental-live-resolvers/LiveResolverStore") @new + @module("relay-runtime/lib/store/live-resolvers/LiveResolverStore") @new external makeLiveStore: (RecordSource.t, storeConfig) => t = "default" @module("relay-runtime") @new @@ -686,8 +686,19 @@ module Store = { module RelayFieldLogger = { @tag("kind") type arg = - | @as("missing_field.log") MissingFieldLog({owner: string, fieldPath: string}) - | @as("missing_field.throw") MissingFieldThrow({owner: string, fieldPath: string}) + | @as("missing_required_field.log") MissingRequiredFieldLog({owner: string, fieldPath: string}) + | @as("missing_required_field.throw") + MissingRequiredFieldThrow({ + owner: string, + fieldPath: string, + }) + | @as("missing_expected_data.log") MissingExpectedData({owner: string, fieldPath: string}) + | @as("missing_expected_data.throw") + MissingExpectedDataThrow({ + owner: string, + fieldPath: string, + handled: bool, + }) | @as("relay_resolver.error") RelayResolverError({ owner: string, diff --git a/packages/rescript-relay/src/RescriptRelay.resi b/packages/rescript-relay/src/RescriptRelay.resi index a6a9bf78..405d250a 100644 --- a/packages/rescript-relay/src/RescriptRelay.resi +++ b/packages/rescript-relay/src/RescriptRelay.resi @@ -744,8 +744,19 @@ module Disposable: { module RelayFieldLogger: { @tag("kind") type arg = - | @as("missing_field.log") MissingFieldLog({owner: string, fieldPath: string}) - | @as("missing_field.throw") MissingFieldThrow({owner: string, fieldPath: string}) + | @as("missing_required_field.log") MissingRequiredFieldLog({owner: string, fieldPath: string}) + | @as("missing_required_field.throw") + MissingRequiredFieldThrow({ + owner: string, + fieldPath: string, + }) + | @as("missing_expected_data.log") MissingExpectedData({owner: string, fieldPath: string}) + | @as("missing_expected_data.throw") + MissingExpectedDataThrow({ + owner: string, + fieldPath: string, + handled: bool, + }) | @as("relay_resolver.error") RelayResolverError({ owner: string, diff --git a/packages/rescript-relay/src/RescriptRelay_Fragment.res b/packages/rescript-relay/src/RescriptRelay_Fragment.res index 5e334ac6..601bd5a9 100644 --- a/packages/rescript-relay/src/RescriptRelay_Fragment.res +++ b/packages/rescript-relay/src/RescriptRelay_Fragment.res @@ -241,3 +241,20 @@ let useRefetchableFragment = ( ), ) } + +@module("relay-runtime/experimental") +external waitForFragmentData_: ( + Environment.t, + fragmentNode<'node>, + 'fragmentRef, +) => promise<'fragment> = "waitForFragmentData" + +let waitForFragmentData = async ( + ~environment, + ~node, + ~convertFragment: 'fragment => 'fragment, + ~fRef, +) => { + let fragmentData = await waitForFragmentData_(environment, node, fRef) + convertFragment(fragmentData) +} diff --git a/packages/rescript-relay/src/RescriptRelay_Fragment.resi b/packages/rescript-relay/src/RescriptRelay_Fragment.resi index 7b6a3cb2..3cd6bf3d 100644 --- a/packages/rescript-relay/src/RescriptRelay_Fragment.resi +++ b/packages/rescript-relay/src/RescriptRelay_Fragment.resi @@ -83,3 +83,10 @@ let useRefetchableFragment: ( ~onComplete: option => unit=?, ) => Disposable.t, ) + +let waitForFragmentData: ( + ~environment: Environment.t, + ~node: fragmentNode<'a>, + ~convertFragment: 'fragment => 'fragment, + ~fRef: 'b, +) => promise<'fragment> diff --git a/packages/rescript-relay/yarn.lock b/packages/rescript-relay/yarn.lock index f92c81c2..db9f8c45 100644 --- a/packages/rescript-relay/yarn.lock +++ b/packages/rescript-relay/yarn.lock @@ -246,13 +246,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.17.12" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.9.2": version "7.18.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.25.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -2541,16 +2548,16 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-relay@17.0.0: - version "17.0.0" - resolved "https://registry.yarnpkg.com/react-relay/-/react-relay-17.0.0.tgz#1f8b6aefaa73b8af8378300d419289a57a6f94c9" - integrity sha512-Kn0CMiKZtWc+EisFPmzuZ53RtDeLlJO+EUVJwqxNkOs5g1jDjVi1v+k48kHeTyim2X43Rr0S2aeailllci5SgQ== +react-relay@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-relay/-/react-relay-18.2.0.tgz#c18dca79c0b88f1bea2787939c4c25c8e7543c26" + integrity sha512-/yHlv4pj3IQQPtDzYLfVk6P4wrOSvYPu/5ySPcRp4xV3pn9xoVOHVczSLcZkRVf72lJu8CIjoT8rn3roaGoFyQ== dependencies: - "@babel/runtime" "^7.0.0" + "@babel/runtime" "^7.25.0" fbjs "^3.0.2" invariant "^2.2.4" nullthrows "^1.1.1" - relay-runtime "17.0.0" + relay-runtime "18.2.0" react@18.2.0: version "18.2.0" @@ -2572,6 +2579,11 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regexp.prototype.flags@^1.2.0: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" @@ -2581,12 +2593,12 @@ regexp.prototype.flags@^1.2.0: define-properties "^1.1.3" functions-have-names "^1.2.2" -relay-runtime@17.0.0: - version "17.0.0" - resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-17.0.0.tgz#771084ea3b44f2f1eb578da861511a5558c4e07b" - integrity sha512-7b2R3G3DP7VHq7/1ltwQfYn3KkTHIB2NNt3KijIZoNQ73avwpOXBEL0MelSXwq8L+K8lcgAW5VAT7o0LUhnJPQ== +relay-runtime@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/relay-runtime/-/relay-runtime-18.2.0.tgz#36e2c88be6e13dcdf987d32a3063e3e491aafa43" + integrity sha512-r4FYWlx1dPwFW+KQnuF1ugwVKR4toIFduCGheEf2paRc6nEEcCIgd2p2Jx2gRF+4niO3mCbRZvqdCoKaznUDzg== dependencies: - "@babel/runtime" "^7.0.0" + "@babel/runtime" "^7.25.0" fbjs "^3.0.2" invariant "^2.2.4" diff --git a/rescript-relay-documentation/docs/getting-started.md b/rescript-relay-documentation/docs/getting-started.md index 007343aa..b9a29261 100644 --- a/rescript-relay-documentation/docs/getting-started.md +++ b/rescript-relay-documentation/docs/getting-started.md @@ -48,8 +48,8 @@ RescriptRelay requires `rescript >= 11.0.0`, `@rescript/react >= 0.12.0`, and as yarn add react@18 react-dom@18 # Add rescript-relay and dependencies to the project -# We currently depend on Relay version 17, so install that exact version -yarn add rescript-relay relay-runtime@17.0.0 react-relay@17.0.0 +# We currently depend on Relay version 18.2, so install that exact version +yarn add rescript-relay relay-runtime@18.2.0 react-relay@18.2.0 ``` After you've installed the packages above, setup ReScript through your `rescript.json` (previously known as `bsconfig.json`) like this on _**MacOS**_ or _**Linux**_: diff --git a/rescript-relay-documentation/docs/relay-resolvers.md b/rescript-relay-documentation/docs/relay-resolvers.md index f047511c..9a8137e8 100644 --- a/rescript-relay-documentation/docs/relay-resolvers.md +++ b/rescript-relay-documentation/docs/relay-resolvers.md @@ -12,7 +12,7 @@ You're encouraged to read the [official Relay documentation on resolvers](https: In order to use Relay resolvers, you need to do a little bit of setup: -First, you need to enable the Relay resolvers feature flag for the compiler in your `relay.config.js`: +First, if you're on lower than version `3.1.0` of RescriptRelay then you need to enable the Relay resolvers feature flag for the compiler in your `relay.config.js`: ```js title="relay.config.js" module.exports = { @@ -25,13 +25,15 @@ module.exports = { }; ``` -You then need to enable the Relay resolver feature in runtime as well. Finally, you need to create a "live store" instead of a regular store when setting up the Relay store. +You also then need to enable the Relay resolver feature in runtime as well. + +Finally, you need to create a "live store" instead of a regular store when setting up the Relay store, regardless of the RescriptRelay version you're using. Here's how you can do the above easily when setting up your environment: ```rescript // change-line -RescriptRelay.relayFeatureFlags.enableRelayResolvers = true +RescriptRelay.relayFeatureFlags.enableRelayResolvers = true // If on a version lower than 3.1.0 let environment = RescriptRelay.Environment.make( ~network, diff --git a/rescript-relay-documentation/docs/using-fragments.md b/rescript-relay-documentation/docs/using-fragments.md index dfb94a0b..6d9f24b9 100644 --- a/rescript-relay-documentation/docs/using-fragments.md +++ b/rescript-relay-documentation/docs/using-fragments.md @@ -193,7 +193,7 @@ let make = (~user) => { There's more fancy stuff you can do with `@alias`, including controlling what the property name for the fragment ends up as in the types. You're encouraged to read the [official Relay docs](https://relay.dev/docs/guides/alias-directive) to learn more. -Also, please note you'll need to enable `@alias` in your Relay config: +Also, please note that if you're under version `3.1.0` of RescriptRelay you'll need to enable `@alias` in your Relay config: ```javascript // relay.config.js