From 3e79b561549377761a8c3f00209f5759ceb405b3 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 4 Dec 2024 22:24:41 +0100 Subject: [PATCH 1/7] up packages, and pull latest compiler --- packages/relay | 2 +- .../__tests__/Test_requiredFieldLogger.res | 2 +- .../TestAliasedFragmentsQuery_graphql.res | 38 ++++++---- .../TestCodesplitQuery_graphql.res | 76 ++++++++++++------- ...estFragmentRequiredPlural_user_graphql.res | 3 +- .../TestFragmentRequired_user_graphql.res | 3 +- .../TestRelayResolversAllQuery_graphql.res | 3 +- .../TestRequiredFieldLoggerQuery_graphql.res | 3 +- .../__generated__/UserAvatar_user_graphql.res | 19 +++-- packages/rescript-relay/package.json | 8 +- packages/rescript-relay/relay.config.js | 6 -- packages/rescript-relay/src/RescriptRelay.res | 19 ++++- .../rescript-relay/src/RescriptRelay.resi | 15 +++- packages/rescript-relay/yarn.lock | 36 ++++++--- 14 files changed, 146 insertions(+), 87 deletions(-) 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_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__/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..6448709a 100644 --- a/packages/rescript-relay/package.json +++ b/packages/rescript-relay/package.json @@ -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/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/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" From 43c779bbf42bb1e1b978a4b7df865e60f2c103a0 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 5 Dec 2024 07:30:02 +0100 Subject: [PATCH 2/7] bind waitForFragmentData --- .../__tests__/Test_nonReact-tests.js | 25 +++ .../__tests__/Test_nonReact.res | 35 +++ .../TestNonReactQuery_graphql.res | 206 ++++++++++++++++++ .../TestNonReact_user_graphql.res | 83 +++++++ .../rescript-relay-ppx/library/Fragment.ml | 7 + .../library/UncurriedUtils.ml | 14 +- .../src/RescriptRelay_Fragment.res | 17 ++ .../src/RescriptRelay_Fragment.resi | 7 + 8 files changed, 390 insertions(+), 4 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 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__/__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/rescript-relay-ppx/library/Fragment.ml b/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml index 3090f32d..db428a39 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Fragment.ml @@ -42,6 +42,13 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo ~fRef: (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) ~node:[%e valFromGeneratedModule ["node"]]]; + [%stri + let waitForFragmentData ~environment fRef = + RescriptRelay_Fragment.waitForFragmentData ~environment + ~convertFragment + ~fRef: + (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) + ~node:[%e valFromGeneratedModule ["node"]]]; [%stri let useOpt fRef : [%t typeFromGeneratedModule ["Types"; "fragment"]] option 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_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> From 78c505a8b49d381a215e7be4114ef2a93b105b76 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 5 Dec 2024 07:47:05 +0100 Subject: [PATCH 3/7] 3.1.0 --- CHANGELOG.md | 5 +++++ packages/rescript-relay/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a36358..e6a05a4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # master +# 3.1.0 + +- **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. + # 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/rescript-relay/package.json b/packages/rescript-relay/package.json index 6448709a..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", From 89094ab2f57be6714f4b4ce1245677f8b2895d29 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 5 Dec 2024 08:37:53 +0100 Subject: [PATCH 4/7] add experimental non React mode to the PPX --- CHANGELOG.md | 1 + .../bin/RescriptRelayPpxApp.ml | 5 + .../rescript-relay-ppx/library/Fragment.ml | 46 +++--- .../rescript-relay-ppx/library/Mutation.ml | 73 +++++---- .../library/NonReactUtils.ml | 1 + .../rescript-relay-ppx/library/Query.ml | 150 ++++++++++-------- .../library/RescriptRelayPpxLibrary.ml | 1 + 7 files changed, 156 insertions(+), 121 deletions(-) create mode 100644 packages/rescript-relay/rescript-relay-ppx/library/NonReactUtils.ml diff --git a/CHANGELOG.md b/CHANGELOG.md index e6a05a4b..227f0415 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - **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 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 db428a39..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 : @@ -42,13 +53,6 @@ let make ~loc ~moduleName ~refetchableQueryName ~extractedConnectionInfo ~fRef: (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) ~node:[%e valFromGeneratedModule ["node"]]]; - [%stri - let waitForFragmentData ~environment fRef = - RescriptRelay_Fragment.waitForFragmentData ~environment - ~convertFragment - ~fRef: - (fRef |. [%e valFromGeneratedModule ["getFragmentRef"]]) - ~node:[%e valFromGeneratedModule ["node"]]]; [%stri let useOpt fRef : [%t typeFromGeneratedModule ["Types"; "fragment"]] option @@ -62,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 : @@ -92,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 : @@ -103,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..a71d4262 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Query.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Query.ml @@ -9,81 +9,93 @@ let make ~loc ~moduleName ~hasRawResponseType ~hasAutocodesplitDirective = (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 - external mkQueryRefOpt : - [%t typeFromGeneratedModule ["queryRef"]] option -> - [%t typeFromGeneratedModule ["queryRef"]] option = "%identity"]; - [%stri - 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 -> + ([ + [%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 + external mkQueryRefOpt : + [%t typeFromGeneratedModule ["queryRef"]] option -> + [%t typeFromGeneratedModule ["queryRef"]] option + = "%identity"]; + [%stri + external mkQueryRef : + [%t typeFromGeneratedModule ["queryRef"]] -> + [%t typeFromGeneratedModule ["queryRef"]] = "%identity"]; + ] + @ + if not !NonReactUtils.enabled then + [ + [%stri + let use = + RescriptRelay_Query.useQuery ~convertVariables + ~convertResponse + ~node:[%e valFromGeneratedModule ["node"]]]; [%stri - let commitLocalPayload = - RescriptRelay_Query.commitLocalPayload ~convertVariables - ~convertWrapRawResponse - ~node:[%e valFromGeneratedModule ["node"]]] - | false -> [%stri ()]); - ]; - (match hasAutocodesplitDirective with - | true -> + 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 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 From cc5ecd408254066952c8a667fd7b943a9800260f Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 5 Dec 2024 09:17:42 +0100 Subject: [PATCH 5/7] fix inclusion --- .../rescript-relay-ppx/library/Query.ml | 138 +++++++++--------- 1 file changed, 67 insertions(+), 71 deletions(-) diff --git a/packages/rescript-relay/rescript-relay-ppx/library/Query.ml b/packages/rescript-relay/rescript-relay-ppx/library/Query.ml index a71d4262..d204ac82 100644 --- a/packages/rescript-relay/rescript-relay-ppx/library/Query.ml +++ b/packages/rescript-relay/rescript-relay-ppx/library/Query.ml @@ -9,84 +9,80 @@ let make ~loc ~moduleName ~hasRawResponseType ~hasAutocodesplitDirective = (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 - external mkQueryRefOpt : - [%t typeFromGeneratedModule ["queryRef"]] option -> - [%t typeFromGeneratedModule ["queryRef"]] option - = "%identity"]; - [%stri - external mkQueryRef : - [%t typeFromGeneratedModule ["queryRef"]] -> - [%t typeFromGeneratedModule ["queryRef"]] = "%identity"]; - ] - @ - if not !NonReactUtils.enabled then - [ + [ + [%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 + external mkQueryRefOpt : + [%t typeFromGeneratedModule ["queryRef"]] option -> + [%t typeFromGeneratedModule ["queryRef"]] option = "%identity"]; + [%stri + external mkQueryRef : + [%t typeFromGeneratedModule ["queryRef"]] -> + [%t typeFromGeneratedModule ["queryRef"]] = "%identity"]; + ] + @ (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 use = - RescriptRelay_Query.useQuery ~convertVariables - ~convertResponse + let fetch = + RescriptRelay_Query.fetch ~convertResponse ~convertVariables ~node:[%e valFromGeneratedModule ["node"]]]; [%stri - let useLoader = - RescriptRelay_Query.useLoader ~convertVariables - ~mkQueryRef:mkQueryRefOpt + let fetchPromised = + RescriptRelay_Query.fetchPromised ~convertResponse + ~convertVariables ~node:[%e valFromGeneratedModule ["node"]]]; [%stri - let usePreloaded = - RescriptRelay_Query.usePreloaded ~convertResponse - ~mkQueryRef + let retain = + RescriptRelay_Query.retain ~convertVariables ~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"]]]; + (match hasRawResponseType with + | true -> [%stri - 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 ()]); - ]); + let commitLocalPayload = + RescriptRelay_Query.commitLocalPayload ~convertVariables + ~convertWrapRawResponse + ~node:[%e valFromGeneratedModule ["node"]]] + | false -> [%stri ()]); + ]; (match (!NonReactUtils.enabled, hasAutocodesplitDirective) with | true, _ -> [] | false, true -> From 2af7412bd41f9faebb0c515b7fe30e920d966ebd Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 14 Dec 2024 21:37:15 +0100 Subject: [PATCH 6/7] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 227f0415..21af31cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # 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"]]`. From 7dd6549003cf8dce697a03a90bc5e63d32eb28c3 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 14 Dec 2024 21:40:24 +0100 Subject: [PATCH 7/7] up docs --- rescript-relay-documentation/docs/getting-started.md | 4 ++-- rescript-relay-documentation/docs/relay-resolvers.md | 8 +++++--- rescript-relay-documentation/docs/using-fragments.md | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) 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