diff --git a/rescript-relay-documentation/docs/api-reference.md b/rescript-relay-documentation/docs/api-reference.md index 05f5a989..386c7c6a 100644 --- a/rescript-relay-documentation/docs/api-reference.md +++ b/rescript-relay-documentation/docs/api-reference.md @@ -185,7 +185,7 @@ Use it like this: `makeArguments({ "someArgument": someValue, "anotherArgument": ## [generateClientID](#generateclientid) ```rescript -let generateClientID: (~dataId: dataId, ~storageKey: string, ~index: int=?, unit) => dataId +let generateClientID: (~dataId: dataId, ~storageKey: string, ~index: int=?) => dataId ``` > Read more about: [dataId](#dataid) @@ -320,8 +320,7 @@ Read the following section on working with the Relay store: https://relay.dev/do let getLinkedRecords: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => option>> ``` @@ -352,7 +351,7 @@ Gets the [dataId](#dataid) for a particular record. ### [RecordProxy.getLinkedRecord](#recordproxygetlinkedrecord) ```rescript -let getLinkedRecord: (t, ~name: string, ~arguments: arguments=?, unit) => option +let getLinkedRecord: (t, ~name: string, ~arguments: arguments=?) => option ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -366,8 +365,7 @@ let getOrCreateLinkedRecord: ( t, ~name: string, ~typeName: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -388,7 +386,7 @@ Returns the `__typename` of this particular record. ### [RecordProxy.getValueString](#recordproxygetvaluestring) ```rescript -let getValueString: (t, ~name: string, ~arguments: arguments=?, unit) => option +let getValueString: (t, ~name: string, ~arguments: arguments=?) => option ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -401,8 +399,7 @@ Returns a field value, expecting it to be a string. let getValueStringArray: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => option>> ``` @@ -413,7 +410,7 @@ Returns a field value, expecting it to be an array of strings. ### [RecordProxy.getValueInt](#recordproxygetvalueint) ```rescript -let getValueInt: (t, ~name: string, ~arguments: arguments=?, unit) => option +let getValueInt: (t, ~name: string, ~arguments: arguments=?) => option ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -426,8 +423,7 @@ Returns a field value, expecting it to be an int. let getValueIntArray: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => option>> ``` @@ -438,7 +434,7 @@ Returns a field value, expecting it to be an array of ints. ### [RecordProxy.getValueFloat](#recordproxygetvaluefloat) ```rescript -let getValueFloat: (t, ~name: string, ~arguments: arguments=?, unit) => option +let getValueFloat: (t, ~name: string, ~arguments: arguments=?) => option ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -451,8 +447,7 @@ Returns a field value, expecting it to be a float. let getValueFloatArray: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => option>> ``` @@ -463,7 +458,7 @@ Returns a field value, expecting it to be an array of floats. ### [RecordProxy.getValueBool](#recordproxygetvaluebool) ```rescript -let getValueBool: (t, ~name: string, ~arguments: arguments=?, unit) => option +let getValueBool: (t, ~name: string, ~arguments: arguments=?) => option ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -476,8 +471,7 @@ Returns a field value, expecting it to be a boolean. let getValueBoolArray: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => option>> ``` @@ -488,7 +482,7 @@ Returns a field value, expecting it to be an array of booleans. ### [RecordProxy.setLinkedRecord](#recordproxysetlinkedrecord) ```rescript -let setLinkedRecord: (t, ~record: t, ~name: string, ~arguments: arguments=?, unit) => t +let setLinkedRecord: (t, ~record: t, ~name: string, ~arguments: arguments=?) => t ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -502,8 +496,7 @@ let setLinkedRecords: ( t, ~records: array>, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -514,7 +507,7 @@ Sets an array of [RecordProxy.t](#recordproxyt) as the linked records for a part ### [RecordProxy.setValueString](#recordproxysetvaluestring) ```rescript -let setValueString: (t, ~value: string, ~name: string, ~arguments: arguments=?, unit) => t +let setValueString: (t, ~value: string, ~name: string, ~arguments: arguments=?) => t ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -528,8 +521,7 @@ let setValueStringArray: ( t, ~value: array, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -540,7 +532,7 @@ Sets an array of strings as field value. ### [RecordProxy.setValueInt](#recordproxysetvalueint) ```rescript -let setValueInt: (t, ~value: int, ~name: string, ~arguments: arguments=?, unit) => t +let setValueInt: (t, ~value: int, ~name: string, ~arguments: arguments=?) => t ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -554,8 +546,7 @@ let setValueIntArray: ( t, ~value: array, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -566,7 +557,7 @@ Sets an array of ints as field value. ### [RecordProxy.setValueFloat](#recordproxysetvaluefloat) ```rescript -let setValueFloat: (t, ~value: float, ~name: string, ~arguments: arguments=?, unit) => t +let setValueFloat: (t, ~value: float, ~name: string, ~arguments: arguments=?) => t ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -580,8 +571,7 @@ let setValueFloatArray: ( t, ~value: array, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -592,7 +582,7 @@ Sets an array of floats as field value. ### [RecordProxy.setValueBool](#recordproxysetvaluebool) ```rescript -let setValueBool: (t, ~value: bool, ~name: string, ~arguments: arguments=?, unit) => t +let setValueBool: (t, ~value: bool, ~name: string, ~arguments: arguments=?) => t ``` > Read more about: [RecordProxy.t](#recordproxyt), [arguments](#arguments) @@ -606,8 +596,7 @@ let setValueBoolArray: ( t, ~value: array, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -621,8 +610,7 @@ Sets an array of booleans as field value. let setValueToUndefined: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -636,8 +624,7 @@ Sets the field value to `undefined` (meaning Relay will treat it as missing data let setValueToNull: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -651,8 +638,7 @@ Sets the field value to `null`. let setLinkedRecordToUndefined: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -666,8 +652,7 @@ Sets this linked record to `undefined` (meaning Relay will treat it as missing d let setLinkedRecordToNull: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -681,8 +666,7 @@ Sets this linked record to `null`. let setLinkedRecordsToUndefined: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -696,8 +680,7 @@ Sets the field holding these linked records to `undefined` (meaning Relay will t let setLinkedRecordsToNull: ( t, ~name: string, - ~arguments: arguments=?, - unit, + ~arguments: arguments=? ) => t ``` @@ -811,8 +794,7 @@ Read the Relay docs section on [ConnectionHandler](https://relay.dev/docs/en/rel let getConnection: ( ~record: RecordProxy.t, ~key: string, - ~filters: arguments=?, - unit, + ~filters: arguments=? ) => option ``` @@ -841,8 +823,7 @@ Creates an edge for a particular connection. let insertEdgeBefore: ( ~connection: RecordProxy.t, ~newEdge: RecordProxy.t, - ~cursor: string=?, - unit, + ~cursor: string=? ) => unit ``` @@ -856,8 +837,7 @@ Inserts an edge into a connection _before_ the provided cursor. If no cursor is let insertEdgeAfter: ( ~connection: RecordProxy.t, ~newEdge: RecordProxy.t, - ~cursor: string=?, - unit, + ~cursor: string=? ) => unit ``` @@ -898,8 +878,7 @@ let makeObserver: ( ~next: 'response => unit=?, ~error: Js.Exn.t => unit=?, ~complete: unit => unit=?, - ~unsubscribe: subscription => unit=?, - unit, + ~unsubscribe: subscription => unit=? ) => observer<'response> ``` @@ -1001,8 +980,7 @@ The type representing an instantiated `NetworkLayer`. ```rescript let makePromiseBased: ( ~fetchFunction: fetchFunctionPromise, - ~subscriptionFunction: subscribeFn=?, - unit, + ~subscriptionFunction: subscribeFn=? ) => t ``` @@ -1015,8 +993,7 @@ The type representing an instantiated `NetworkLayer`. ```rescript let makeObservableBased: ( ~observableFunction: fetchFunctionObservable, - ~subscriptionFunction: subscribeFn=?, - unit, + ~subscriptionFunction: subscribeFn=? ) => t ``` @@ -1075,8 +1052,7 @@ let make: ( ~source: RecordSource.t, ~gcReleaseBufferSize: /* `gcReleaseBufferSize` controls how many queries are allowed to be cached by default. Increase this to increase the size of the cache. */ int=?, - ~queryCacheExpirationTime: int /* `queryCacheExpirationTime` sets a TTL (time to live) for all queries. If that time passes, the data is considered stale and is evicted from the store. Default is no TTL. */=?, - unit, + ~queryCacheExpirationTime: int /* `queryCacheExpirationTime` sets a TTL (time to live) for all queries. If that time passes, the data is considered stale and is evicted from the store. Default is no TTL. */=? ) => t ``` @@ -1114,7 +1090,7 @@ let make = (~serializedRecords: RescriptRelay.recordSourceRecords) => { let environment = RescriptRelay.useEnvironmentFromContext() /* Make sure we only run this once */ - React.useEffect2(() => { + React.useEffect(() => { /* This will publish the records to the existing store */ environment->RescriptRelay.Store.publish(serializedRecords) None @@ -1218,8 +1194,7 @@ let make: ( ~typeName: string, ) => string=?, ~treatMissingFieldsAsNull: bool=?, - ~missingFieldHandlers: array=?, - unit, + ~missingFieldHandlers: array=? ) => t ``` diff --git a/rescript-relay-documentation/docs/enums.md b/rescript-relay-documentation/docs/enums.md index 7f8d33b0..c914cd9b 100644 --- a/rescript-relay-documentation/docs/enums.md +++ b/rescript-relay-documentation/docs/enums.md @@ -79,7 +79,7 @@ let (newStatus, setNewStatus) = React.useState(() => ticket.status) // Uh-oh, we can't do this because we can't guarantee that `ticket.status` above, // which is assigned to `newStatus`, is the values we expect it to be, since // the server might've changed the enum members after we've deployed. -setTicketStatus(~variables={id: ticket.id, newStatus: newStatus}, ())) +setTicketStatus(~variables={id: ticket.id, newStatus: newStatus}) ``` Luckily, RescriptRelay gives you utils to deal with this situation. Whenever you want to move between the _unsafe_ enum coming directly from the server, and a _safe_ version of that enum that you know is correct, you can use `_decode`. This will validate that the enum that came from the server is in fact in the shape you expect. The same example as above, but now ensuring that the enum in the state is actually what we want it to be: @@ -93,7 +93,7 @@ let (newStatus, setNewStatus) = React.useState(() => // sets a default value instead. ticket.status ->TicketFragment.ticketStatus_decode - ->Belt.Option.getWithDefault(#OnHold) + ->Option.getOr(#OnHold) ) // Yay, `newStatus` is now safe to use like we expect it to be! diff --git a/rescript-relay-documentation/docs/getting-started.md b/rescript-relay-documentation/docs/getting-started.md index 0223cd0d..7da9dc98 100644 --- a/rescript-relay-documentation/docs/getting-started.md +++ b/rescript-relay-documentation/docs/getting-started.md @@ -30,7 +30,7 @@ You will have the absolute best experience using RescriptRelay in concurrent mod Not all new APIs from React are currently bound in the official `@rescript/react` bindings. RescriptRelay therefore ships `ReactExperimental` and `ReactDOMExperimental`, modules with a few bindings to suspense and concurrent mode-related React API's with no official bindings yet. You're encouraged to use this until there's an official alternative. -This means that you'll need React 18 (in `rc` at the time of writing) and ReactDOM. +This means that you'll need React 18 and ReactDOM. #### A short note on the workflow of using Relay @@ -49,22 +49,31 @@ You really don't need to care about the generated artifacts though, RescriptRela ## Installation -RescriptRelay requires `rescript >= 10.1`, `@rescript/react >= 0.11.0`, and as mentioned [here](#concurrent-mode-is-encouraged), it works best with React 18 (`react@18 react-dom@18`). Let's start by installing the dependencies: +RescriptRelay requires `rescript >= 11.0.0`, `@rescript/react >= 0.12.0`, and as mentioned [here](#concurrent-mode-is-encouraged), it works best with React 18 (`react@18 react-dom@18`). Let's start by installing the dependencies: -```bash +```bash title="Terminal" # Add React 18 yarn add react@18 react-dom@18 # Add rescript-relay and dependencies to the project -# We currently depend on Relay version 15, so install that exact version -yarn add rescript-relay relay-runtime@15.0.0 react-relay@15.0.0 +# We currently depend on Relay version 16, so install that exact version +yarn add rescript-relay relay-runtime@16.0.0 react-relay@16.0.0 ``` -After you've installed the packages above, setup ReScript through your `bsconfig.json` like this: +After you've installed the packages above, setup ReScript through your `rescript.json` (previously known as `bsconfig.json`) like this on _**MacOS**_ or _**Linux**_: -```json +```json title="rescript.json" ... -"ppx-flags": ["rescript-relay/ppx"], +"ppx-flags": [["rescript-relay/ppx", "-uncurried"]], +"bs-dependencies": ["@rescript/react", "rescript-relay"], +... +``` + +or like this on _**Windows**_: + +```json title="rescript.json" +... +"ppx-flags": [["rescript-relay/ppx.exe", "-uncurried"]], "bs-dependencies": ["@rescript/react", "rescript-relay"], ... ``` @@ -80,7 +89,7 @@ Ensure that only the new React 18 versions are used by doing the following: 1. Open `package.json` and look for `react` and `react-dom`. In the versions field you'll see something like `18.0.0` - copy that version number. 2. Add an entry for both `react` and `react-dom` with that version number to your `resolutions`. The final configuration should look something like this: -```json +```json title="package.json" ... "resolutions": { "react": "18.0.0", @@ -93,8 +102,7 @@ Ensure that only the new React 18 versions are used by doing the following: Add a `relay.config.js` to your project root with the following in it: -```js -// relay.config.js +```js title="relay.config.js" module.exports = { src: "./src", // Path to the folder containing your ReScript files schema: "./schema.graphql", // Path to the schema.graphql you've exported from your API. Don't know what this is? It's a saved introspection of what your schema looks like. You can run `npx get-graphql-schema http://path/to/my/graphql/server > schema.graphql` in your root to generate it @@ -120,8 +128,7 @@ Please note that RescriptRelay enforces two things that regular Relay does not: We'll also add a script to our `package.json` to run the Relay compiler: -```json -// package.json +```json title="package.json" ... "scripts": { "relay": "rescript-relay-compiler", @@ -143,10 +150,11 @@ The Relay compiler is really awesome. If you're interested there's plenty more t Finally time for some actual code. Next thing is setting up the Relay environment. The Relay environment consists of a network layer responsible for dispatching your GraphQL queries, and a store responsible for storing data and supplying it to your components. -You're encouraged to put this in a separate file like `RelayEnv.re` or similar. Setting it up looks like this (using `@glennsl/rescript-fetch` for fetching, which you can find [installation instructions for here](https://github.com/glennsl/rescript-fetch)): +You're encouraged to put this in a separate file like `RelayEnv.res` or similar. Setting it up looks like this (using `@glennsl/rescript-fetch` for fetching, which you can find [installation instructions for here](https://github.com/glennsl/rescript-fetch)): -```rescript -/* RelayEnv.res */ +```rescript title="RelayEnv.res" +/* This is a Rescript's standard library, typically opened globally in rescript.json */ +open RescriptCore /* This is just a custom exception to indicate that something went wrong. */ exception Graphql_error(string) @@ -167,8 +175,8 @@ let fetchQuery: RescriptRelay.Network.fetchFunctionPromise = async ( { method: #POST, body: {"query": operation.text, "variables": variables} - ->Js.Json.stringifyAny - ->Belt.Option.getExn + ->JSON.stringifyAny + ->Option.getExn ->Body.string, headers: Headers.fromObject({ "content-type": "application/json", @@ -184,16 +192,14 @@ let fetchQuery: RescriptRelay.Network.fetchFunctionPromise = async ( } } -let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=fetchQuery, ()) +let network = RescriptRelay.Network.makePromiseBased(~fetchFunction=fetchQuery) let environment = RescriptRelay.Environment.make( ~network, ~store=RescriptRelay.Store.make( ~source=RescriptRelay.RecordSource.make(), - ~gcReleaseBufferSize=10, /* This sets the query cache size to 10 */ - (), - ), - (), + ~gcReleaseBufferSize=10 /* This sets the query cache size to 10 */ + ) ) ``` @@ -205,8 +211,7 @@ There, we now have a Relay environment! We only have two more things to fix befo Your Relay environment needs to be available in React's context in your app. To fix that, wrap your app in a ``: -```rescript -/* Index.res */ +```rescript title="Index.res" ReactDOMExperimental.renderConcurrentRootAtElementWithId( diff --git a/rescript-relay-documentation/docs/making-queries.md b/rescript-relay-documentation/docs/making-queries.md index b8180fed..0e64e262 100644 --- a/rescript-relay-documentation/docs/making-queries.md +++ b/rescript-relay-documentation/docs/making-queries.md @@ -41,8 +41,7 @@ let make = (~userId) => { let queryData = Query.use( ~variables={ userId: userId, - }, - (), + } ) switch queryData.userById { @@ -72,7 +71,7 @@ RescriptRelay lets you leverage preloading in 3 different ways, all suitable for In RescriptRelay, every `%relay()` node containing a query automatically generates a `useLoader` hook. That hook returns a tuple of 3 things: `(option, loadQuery, disposeQuery)`. 1. `option` - an option of a query reference. This query reference can be passed to `Query.usePreloaded`, like `let queryData = Query.usePreloaded(~queryRef=queryRef)`, to get the data for the query as soon as it's available. -2. `loadQuery` - a function that'll start loading the data for this query. You call it like `loadQuery(~variables={...}, ~fetchPolicy=?, ~networkCacheConfig=?, ())`. As soon as you've called this function, the `queryRef` (first item of the tuple) will be populated, and you can pass that `queryRef` to `usePreloaded`. +2. `loadQuery` - a function that'll start loading the data for this query. You call it like `loadQuery(~variables={...}, ~fetchPolicy=?, ~networkCacheConfig=?)`. As soon as you've called this function, the `queryRef` (first item of the tuple) will be populated, and you can pass that `queryRef` to `usePreloaded`. 3. `disposeQuery` - a function that disposes the query reference manually. Calling this would turn `option(queryRef)` into `None`. So, the typical way to preload a query would be like this: @@ -102,7 +101,7 @@ let make = (~userId) => { switch queryRef { | Some(queryRef) => | None => - } @@ -280,8 +279,6 @@ As shown in the snippet above, `Query.use` is a React hook that dispatches your ##### Parameters -_Please note that this function must be called with an ending unit `()` if not all arguments are supplied._ - | Name | Type | Required | Notes | | -------------------- | -------------------------------------------- | -------- | ----------------------------------------------------------------------------------------- | | `variables` | `'variables` | _Yes_ | Variables derived from the GraphQL operation. `unit` if no variables are defined. | @@ -300,15 +297,14 @@ Query.fetch(~environment, ~variables=(), ~onResult=res => switch res { | Ok(res) => Js.log(res) | Error(_) => Js.log("Error") - }, - () + } ) ``` Please note though that `fetch` does not necessarily retain data in the Relay store, meaning it's really only suitable for data you only need once at a particular point in time. For refetching data, please check out [refetching and loading more data](refetching-and-loading-more-data). -The results are delivered through a `Belt.Result.t` in the `onResult` callback. +The results are delivered through a `RescriptCore.Result.t` in the `onResult` callback. > `fetch` uses Relay's `fetchQuery` under the hood, which you can [read more about here](https://relay.dev/docs/api-reference/fetch-query). @@ -329,7 +325,7 @@ The same as `fetch`, but returns a promise instead of using a callback. Using it looks something like this: ```rescript -Query.fetchPromised(~environment, ~variables=(), ()) +Query.fetchPromised(~environment, ~variables=()) ->Js.Promise.then_(res => { Js.log(res) Js.Promise.resolve() @@ -362,7 +358,7 @@ Pass this `queryRef` to the `Query.usePreloaded` hook to get data for the query. A function that starts loading the query, populating `queryRef`. Signature looks like this: -`let loadQuery: (~variables: queryVariables, ~fetchPolicy: fetchPolicy=?, ~networkCacheConfig: networkCacheConfig=?, ()) => unit;` +`let loadQuery: (~variables: queryVariables, ~fetchPolicy: fetchPolicy=?, ~networkCacheConfig: networkCacheConfig=?) => unit;` Call this as soon as possible to start your query. diff --git a/rescript-relay-documentation/docs/migrating-to-v3.md b/rescript-relay-documentation/docs/migrating-to-v3.md index fd568d49..092aeaea 100644 --- a/rescript-relay-documentation/docs/migrating-to-v3.md +++ b/rescript-relay-documentation/docs/migrating-to-v3.md @@ -150,7 +150,7 @@ yarn rescript build Migrating is just about removing all object maker function usage and using regular records instead: ```rescript -let doLogin = React.useCallback5(() => { +let doLogin = React.useCallback(() => { let _ = login( // color2 ~variables=LoginMutation.makeVariables(~username=state.username, ~password=state.password), diff --git a/rescript-relay-documentation/docs/mutations.md b/rescript-relay-documentation/docs/mutations.md index f299bd87..18cb313d 100644 --- a/rescript-relay-documentation/docs/mutations.md +++ b/rescript-relay-documentation/docs/mutations.md @@ -43,8 +43,7 @@ let make = () => { id: todoItem.id, text: newText, }, - }, - (), + } )}> {React.string(isMutating ? "Updating..." : "Update")} @@ -118,17 +117,13 @@ let make = (~user) => { // This creates an id for the connection above with `minimumCommonFriends` as 10, and `onlineStatuses` at its default value (which is `[Idle]`). // Notice that we use `__id` from the user - that's because `makeConnectionId` needs to know the _owner_ for the connection you're looking for. It doesn't need the field of the connection, just the owner itself. let connectionId = - user.__id->UserFriendsList_user_graphql.makeConnectionId( - ~minimumCommonFriends=10, - (), - ) + user.__id->UserFriendsList_user_graphql.makeConnectionId(~minimumCommonFriends=10) // This creates an id with both `minimumCommonFriends` and `onlineStatuses` having explicit values. let connectionId2 = user.__id->UserFriendsList_user_graphql.makeConnectionId( ~minimumCommonFriends=10, - ~onlineStatuses=[#Online, #Idle], - (), + ~onlineStatuses=[#Online, #Idle] ) // We can then use these connection ID:s to either pass into the `connections: [ID!]!` argument of the declarative updater directives, or we can use them to imperatively pull out a connection from the store like this: @@ -173,7 +168,6 @@ mutate( updatedTodoItem: Some({"id": todoItem.id, "text": todoItem.text}), }), }, - (), ) ``` @@ -289,8 +283,6 @@ A React hook for running and keeping track of the mutation. Returns a tuple of ` ##### Parameters -_Please note that this function must be called with an ending unit `()` if not all arguments are supplied._ - | Name | Type | Required | Notes | | -------------------- | -------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `variables` | `'variables` | _Yes_ | Variables derived from the GraphQL operation | @@ -306,8 +298,6 @@ Commits the specified mutation to Relay and returns a `Disposable.t` that allow ##### Parameters -_Please note that this function must be called with an ending unit `()` if not all arguments are supplied._ - | Name | Type | Required | Notes | | -------------------- | ---------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `environment` | `Environment.t` | _Yes_ | | diff --git a/rescript-relay-documentation/docs/pagination.md b/rescript-relay-documentation/docs/pagination.md index 0f7a48d9..a5cdef04 100644 --- a/rescript-relay-documentation/docs/pagination.md +++ b/rescript-relay-documentation/docs/pagination.md @@ -77,10 +77,10 @@ let make = (~query) => {

{React.string("Recent Tickets")}

{tickets - ->Belt.Array.map(ticket => ) + ->Array.map(ticket => ) ->React.array} {hasNext - ? : React.null} @@ -128,13 +128,13 @@ As shown above, `usePagination` provides helpers for paginating your fragment/co | Name | Type | Note | | ------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | | `data` | `'fragmentData` | The data as defined by the fragment. | -| `loadNext` | `(~count: int, ~onComplete: option(Js.Exn.t) => unit=?, unit) => Disposable.t;` | A function for loading the next `count` nodes of the connection. | -| `loadPrevious` | `(~count: int, ~onComplete: option(Js.Exn.t) => unit=?, unit) => Disposable.t;` | A function for loading the previous `count` nodes of the connection. | +| `loadNext` | `(~count: int, ~onComplete: option(Js.Exn.t) => unit=?) => Disposable.t;` | A function for loading the next `count` nodes of the connection. | +| `loadPrevious` | `(~count: int, ~onComplete: option(Js.Exn.t) => unit=?) => Disposable.t;` | A function for loading the previous `count` nodes of the connection. | | `hasNext` | `bool` | Are there more nodes forward in the connection to fetch? | | `hasPrevious` | `bool` | Are there more nodes backwards in the connection to fetch? | | `isLoadingNext` | `bool` | | | `isLoadingPrevious` | `bool` | | -| `refetch` | `(~variables: 'variables, ~fetchPolicy: fetchPolicy=?, ~onComplete: option(Js.Exn.t) => unit=?, unit) =>` | Refetch the entire connection with potentially new variables. | +| `refetch` | `(~variables: 'variables, ~fetchPolicy: fetchPolicy=?, ~onComplete: option(Js.Exn.t) => unit=?) =>` | Refetch the entire connection with potentially new variables. | ### `useBlockingPagination` diff --git a/rescript-relay-documentation/docs/refetching-and-loading-more-data.md b/rescript-relay-documentation/docs/refetching-and-loading-more-data.md index 3656ba38..98763eef 100644 --- a/rescript-relay-documentation/docs/refetching-and-loading-more-data.md +++ b/rescript-relay-documentation/docs/refetching-and-loading-more-data.md @@ -52,7 +52,7 @@ let make = (~user) => {
{React.string("Age: " ++ string_of_int(bio.age))}
@@ -61,7 +61,7 @@ let make = (~user) => { }} @@ -85,9 +85,9 @@ Let's dive into `makeRefetchVariables`, because this can be a bit tricky to unde In the example above we have variables `$includeFullBio` and `$bioMaxLength`. Let's say this fragment gets rendered with `$includeFullBio = true` and `$bioMaxLength` not set yet. -- If I want to refetch the fragment with `$includeFullBio` changed to `false`, I'd do `makeRefetchVariables(~includeFullBio=Some(false), ())`. `Some(false)` here tells Relay that "I want to change `$includeFullBio` in the refetch to `false`. Use the last value for all other variables". -- If I want to set `$bioMaxLength` to something, I'd do `makeRefetchVariables(~bioMaxLength=Some(200), ())`. This tells Relay "set `bioMaxLength`, leave everything else as is". -- If I have `bioMaxLength` set and I want to refetch data with it _not set at all_ (equivalent of passing `null`), I'd do `makeRefetchVariables(~bioMaxLength=None, ())`. +- If I want to refetch the fragment with `$includeFullBio` changed to `false`, I'd do `makeRefetchVariables(~includeFullBio=Some(false))`. `Some(false)` here tells Relay that "I want to change `$includeFullBio` in the refetch to `false`. Use the last value for all other variables". +- If I want to set `$bioMaxLength` to something, I'd do `makeRefetchVariables(~bioMaxLength=Some(200))`. This tells Relay "set `bioMaxLength`, leave everything else as is". +- If I have `bioMaxLength` set and I want to refetch data with it _not set at all_ (equivalent of passing `null`), I'd do `makeRefetchVariables(~bioMaxLength=None)`. So, notice how `Some(value)` means "set this value", `None` means "unset this value", and leaving out the variable all together from `makeRefetchVariables` means "don't change this variable, reuse the last value". diff --git a/rescript-relay-documentation/docs/subscriptions.md b/rescript-relay-documentation/docs/subscriptions.md index 754b6315..8464a574 100644 --- a/rescript-relay-documentation/docs/subscriptions.md +++ b/rescript-relay-documentation/docs/subscriptions.md @@ -58,16 +58,15 @@ let subscriptionFunction: RescriptRelay.Network.subscribeFn = (config, variables let network = RescriptRelay.Network.makePromiseBased( ~fetchFunction=fetchQuery(token), - ~subscriptionFunction, - (), + ~subscriptionFunction ) let store = { open RescriptRelay - Store.make(~source=RecordSource.make(), ()) + Store.make(~source=RecordSource.make()) } -let environment = RescriptRelay.Environment.make(~network, ~store, ()) +let environment = RescriptRelay.Environment.make(~network, ~store) ``` @@ -112,11 +111,10 @@ module TicketStatusSubscription = %relay( @react.component let make = (~ticketId) => { let environment = RescriptRelay.useEnvironmentFromContext() - React.useEffect2(() => { + React.useEffect(() => { let subscription = TicketStatusSubscription.subscribe( ~environment, - ~variables={id: ticketId}, - (), + ~variables={id: ticketId} ) Some(() => RescriptRelay.Disposable.dispose(subscription)) }, (ticketId, environment)) diff --git a/rescript-relay-documentation/docs/the-node-interface.md b/rescript-relay-documentation/docs/the-node-interface.md index eea191e3..8168fa68 100644 --- a/rescript-relay-documentation/docs/the-node-interface.md +++ b/rescript-relay-documentation/docs/the-node-interface.md @@ -34,8 +34,7 @@ let make = (~id: string) => { let queryData = Query.use( ~variables={ id: id, - }, - (), + } ) {switch queryData.node { @@ -91,8 +90,7 @@ let make = (~id: string) => { let queryData = Query.use( ~variables={ id: id, - }, - (), + } ) {switch queryData.node { diff --git a/rescript-relay-documentation/docs/tutorial/10-mutations-updates.md b/rescript-relay-documentation/docs/tutorial/10-mutations-updates.md index 42f7d3de..c938b0b8 100644 --- a/rescript-relay-documentation/docs/tutorial/10-mutations-updates.md +++ b/rescript-relay-documentation/docs/tutorial/10-mutations-updates.md @@ -161,7 +161,6 @@ But we’re getting ahead of ourselves — let’s make that button trigger the @react.component let make = (~story) => { let data = Fragment.use(story) - switch data { | None => React.null | Some({likeCount, doesViewerLike}) => @@ -185,9 +184,7 @@ let make = (~story) => { | None => React.null | Some({id, likeCount, doesViewerLike}) => { let onLikeButtonClicked = () => { - let variables = StoryLikeButtonLikeMutation.makeVariables(~id, ~doesLike=!doesViewerLike) - commitMutation(~variables, ())->RescriptRelay.Disposable.ignore - () + commitMutation(~variables={id, doesLike: !doesViewerLike})->RescriptRelay.Disposable.ignore }
@@ -198,7 +195,7 @@ let make = (~story) => { } ``` -The mutations `use` hook returns a function to fire the mutation (here named `commitMutation`) and a boolean which is true when the mutation is in flight (here named... `isMutationInFlight`). When calling `commitMutation` we pass in a record called `variables`, created using the `makeVariables` helper. It accepts labelled parameters for the variables defined by the mutation, namely `id` and `doesViewerLike`. This tells the server which story we’re talking about and whether the we are liking or un-liking it. The `id` of the story we’ve read from the fragment, while whether we like it or unlike it comes from toggling whatever the current value that we rendered is. +The mutations `use` hook returns a function to fire the mutation (here named `commitMutation`) and a boolean which is true when the mutation is in flight (here named... `isMutationInFlight`). When calling `commitMutation` we pass in a record called `variables`. It accepts labelled parameters for the variables defined by the mutation, namely `id` and `doesViewerLike`. This tells the server which story we’re talking about and whether the we are liking or un-liking it. The `id` of the story we’ve read from the fragment, while whether we like it or unlike it comes from toggling whatever the current value that we rendered is. The hook also returns a boolean flag that tells us when the mutation is in flight. We can use that to make the user experience nicer by disabling the button while the mutation is happening: @@ -214,21 +211,6 @@ The hook also returns a boolean flag that tells us when the mutation is in fligh
``` -:::tip -The variables object can also be constructed manually, so the call to `commitMutation` becomes -```rescript - commitMutation( - ~variables={ - id: id, - doesLike: doesViewerLike - }, - (), - )->RescriptRelay.Disposable.ignore -``` -For this particular case, whether you do it one way or the other only makes a stylistic difference. However, if a mutation accepts a nullable variable -`makeVariables` is more convenient as it lets you construct the variables record without having to specify variables that you don't want to pass to the mutation. -::: - With this in place, we should now be able to like a story! ## How Relay Automatically Processes Mutation Responses @@ -349,10 +331,8 @@ We only need to call `commitMutation` with the response we're expecting. If the | None => React.null | Some({id, likeCount, doesViewerLike}) => { let onLikeButtonClicked = () => { - let variables = StoryLikeButtonLikeMutation.makeVariables(~id, ~doesLike=!doesViewerLike) - commitMutation( - ~variables, + ~variables={id, doesLike: !doesViewerLike}, // begin-change ~optimisticResponse={ likeStory: Some({ @@ -362,9 +342,8 @@ We only need to call `commitMutation` with the response we're expecting. If the doesViewerLike: Some(!doesViewerLike), }), }), - }, + } // end-change - (), )->RescriptRelay.Disposable.ignore }
@@ -405,7 +384,7 @@ module Fragment = %relay(` ) { // change-line ...StoryCommentsComposerFragment - comments(after: $cursor, first: $count) + comments(after: $cursor, first: $count) @connection(key: "StoryCommentsSection_story_comments") { ... } @@ -489,8 +468,7 @@ let make = (~story) => { ~variables={ id, text, - }, - (), + } )->RescriptRelay.Disposable.ignore // end-change } @@ -526,11 +504,8 @@ let make = (~story) => { }, ~onError=_ => { setText(_ => text) - }, + } // end-change - () - }, - (), )->RescriptRelay.Disposable.ignore } } @@ -611,8 +586,7 @@ let make = (~story) => { // change let connectionId = RescriptRelay.ConnectionHandler.getConnectionID( __id, - "StoryCommentsSection_story_comments", - (), + "StoryCommentsSection_story_comments" ) // end-change commitMutation( @@ -623,8 +597,7 @@ let make = (~story) => { // change-line connections: [connectionId], ... - }, - (), + } )->RescriptRelay.Disposable.ignore }
@@ -678,11 +651,8 @@ let make = (~story) => { }), }), }), - }, + } // end-change - () - }, - (), )->RescriptRelay.Disposable.ignore } } @@ -701,6 +671,6 @@ Mutations let us ask the server to make changes. - Relay automatically merges nodes in the response to nodes in the Store with matching IDs. - The `onCompleted` and `onError` callbacks lets you trigger side-effects (such as restoring or clearing component state), when the mutation finishes. - The `@appendEdge`, `@prependEdge`, and `@deleteEdge` directives let us insert and remove items from the mutation response into Connections in the store. -- We can get optimistic UI by using the `@raw_response_type` directive on the mutation and passing what we expect the mutation response to be to `commitMutation`. +- We can get optimistic UI by using the `@raw_response_type` directive on the mutation and passing what we expect the mutation response to be to `commitMutation`. - Updates to the store via Optimistic responses are rolled back when the mutation completes, so the actual response can be applied instead. diff --git a/rescript-relay-documentation/docs/tutorial/3-query-basics.md b/rescript-relay-documentation/docs/tutorial/3-query-basics.md index 3ef35b8d..0ea53727 100644 --- a/rescript-relay-documentation/docs/tutorial/3-query-basics.md +++ b/rescript-relay-documentation/docs/tutorial/3-query-basics.md @@ -92,7 +92,7 @@ Turn back to the `Newsfeed` component and start by deleting the placeholder data ```rescript @react.component let make = () => { - let data = NewsfeedQuery.use(~variables=(), ()) + let data = NewsfeedQuery.use(~variables=()) switch data.topStory { | None => React.null @@ -218,17 +218,17 @@ The object that `NewsfeedQuery.use` returns has the same shape as the query. For ```json { - topStory: { - title: "Local Yak Named Yak of the Year", - summary: "The annual Yak of the Year awards ceremony ...", - poster: { - name: "Baller Bovine Board", - profilePic: { - url: '/images/baller_bovine_board.jpg', - }, + "topStory": { + "title": "Local Yak Named Yak of the Year", + "summary": "The annual Yak of the Year awards ceremony ...", + "poster": { + "name": "Baller Bovine Board", + "profilePic": { + "url": "/images/baller_bovine_board.jpg" + } }, - thumbnail: { - url: '/images/max_the_yak.jpg', + "thumbnail": { + "url": "/images/max_the_yak.jpg" } } } diff --git a/rescript-relay-documentation/docs/tutorial/4-fragments.md b/rescript-relay-documentation/docs/tutorial/4-fragments.md index 1cf45091..27b62ea8 100644 --- a/rescript-relay-documentation/docs/tutorial/4-fragments.md +++ b/rescript-relay-documentation/docs/tutorial/4-fragments.md @@ -185,7 +185,7 @@ Since `Story.res` now expects a fragment key, we change the `make` funtion of `N ```rescript @react.component let make = () => { - let data = NewsfeedQuery.use(~variables=(), ()) + let data = NewsfeedQuery.use(~variables=()) switch data.topStory { | None => React.null diff --git a/rescript-relay-documentation/docs/tutorial/5-arrays-and-lists.md b/rescript-relay-documentation/docs/tutorial/5-arrays-and-lists.md index f112820c..31a44a26 100644 --- a/rescript-relay-documentation/docs/tutorial/5-arrays-and-lists.md +++ b/rescript-relay-documentation/docs/tutorial/5-arrays-and-lists.md @@ -68,7 +68,7 @@ In the `Newsfeed` component, `data` no longer has a field `topStory`, but now in ```rescript @react.component let make = () => { - let data = NewsfeedQuery.use(~variables=(), ()) + let data = NewsfeedQuery.use(~variables=()) switch data.topStories { | None => React.null @@ -110,7 +110,7 @@ module NewsfeedQuery = %relay(` @react.component let make = () => { - let {topStories} = NewsfeedQuery.use(~variables=(), ()) + let {topStories} = NewsfeedQuery.use(~variables=()) switch topStories { | None => React.null diff --git a/rescript-relay-documentation/docs/tutorial/6-queries-for-interaction.md b/rescript-relay-documentation/docs/tutorial/6-queries-for-interaction.md index d287f46a..842ce2dc 100644 --- a/rescript-relay-documentation/docs/tutorial/6-queries-for-interaction.md +++ b/rescript-relay-documentation/docs/tutorial/6-queries-for-interaction.md @@ -194,7 +194,7 @@ We’ll add a new prop to our component and pass its value in there: // change-line let make = (~posterID) => { // change-line - let data = HovercardQuery.use(~variables={posterID: posterID}, ()) + let data = HovercardQuery.use(~variables={posterID: posterID})
{switch data.node { | None => React.null @@ -293,7 +293,7 @@ As a reminder, this is the `PosterDetailsHovercardContents` component that curre ```rescript @react.component let make = (~posterID) => { - let data = HovercardQuery.use(~variables={posterID: posterID}, ()) + let data = HovercardQuery.use(~variables={posterID: posterID})
{switch data.node { | None => React.null @@ -383,7 +383,7 @@ let make = (~poster) => {
{name->React.string}
loadHoverCardQuery(~variables={posterID: id}, ())}> + targetRef={hoverRef} onBeginHover={_ => loadHoverCardQuery(~variables={posterID: id})}> {switch hovercardQueryRef { | None => React.null | Some(queryRef) => diff --git a/rescript-relay-documentation/docs/tutorial/8-refetchable-fragments.md b/rescript-relay-documentation/docs/tutorial/8-refetchable-fragments.md index 1ae95ae1..32e687d4 100644 --- a/rescript-relay-documentation/docs/tutorial/8-refetchable-fragments.md +++ b/rescript-relay-documentation/docs/tutorial/8-refetchable-fragments.md @@ -172,8 +172,8 @@ let make = (~viewer) => { // change let onSearchStringChanged = value => { setSearchString(_ => value) - let variables = Fragment.makeRefetchVariables(~search=Some(value), ()) - refetch(~variables, ())->RescriptRelay.Disposable.ignore + let variables = Fragment.makeRefetchVariables(~search=Some(value)) + refetch(~variables)->RescriptRelay.Disposable.ignore } // end-change @@ -210,8 +210,8 @@ let make = (~viewer) => { setSearchString(_ => value) // change startTransition(() => { - let variables = Fragment.makeRefetchVariables(~search=Some(value), ()) - refetch(~variables, ())->RescriptRelay.Disposable.ignore + let variables = Fragment.makeRefetchVariables(~search=Some(value)) + refetch(~variables)->RescriptRelay.Disposable.ignore }) // end-change } @@ -224,8 +224,8 @@ let make = (~viewer) => { | None => React.null | Some(contacts) => contacts - ->Belt.Array.keepMap(x => x) - ->Belt.Array.map(contact => ) + ->Array.keepSome + ->Array.map(contact => ) ->React.array }} diff --git a/rescript-relay-documentation/docs/tutorial/9-connections-pagination.md b/rescript-relay-documentation/docs/tutorial/9-connections-pagination.md index bf4a65b9..6242bc41 100644 --- a/rescript-relay-documentation/docs/tutorial/9-connections-pagination.md +++ b/rescript-relay-documentation/docs/tutorial/9-connections-pagination.md @@ -260,7 +260,7 @@ to ```rescript let {data, loadNext} = Fragment.usePagination(story) -let onLoadMore = () => loadNext(~count=3, ())->RescriptRelay.Disposable.ignore +let onLoadMore = () => loadNext(~count=3)->RescriptRelay.Disposable.ignore ``` and pass `onLoadMore` to the button: `` @@ -288,7 +288,7 @@ let make = (~story) => { // change let onLoadMore = () => startTransition(() => { - loadNext(~count=3, ())->ignore + loadNext(~count=3)->RescriptRelay.Disposable.ignore }) // end-change @@ -357,7 +357,7 @@ We’ve replaced `topStories` with `viewer`’s `newsfeedStories`, adding a `fir ```rescript @react.component let make = () => { - let {viewer} = NewsfeedQuery.use(~variables=(), ()) + let {viewer} = NewsfeedQuery.use(~variables=()) switch viewer { | None => React.null @@ -404,7 +404,7 @@ let make = (~viewer as viewerRef) => { <> {stories - ->Belt.Array.map(story => ) + ->Array.map(story => ) ->React.array} } @@ -424,7 +424,7 @@ module NewsfeedQuery = %relay(` @react.component let make = () => { - let {viewer} = NewsfeedQuery.use(~variables=(), ()) + let {viewer} = NewsfeedQuery.use(~variables=())
{switch viewer { @@ -480,7 +480,7 @@ let make = (~viewer as viewerRef) => { <> {stories - ->Belt.Array.map(story => ) + ->Array.map(story => ) ->React.array} } @@ -498,11 +498,11 @@ let make = (~viewer as viewerRef) => { let stories = Fragment.getConnectionNodes(data.newsfeedStories) // change-line - let onEndReached = () => loadNext(~count=3, ())->ignore + let onEndReached = () => loadNext(~count=3)->RescriptRelay.Disposable.ignore <> {stories - ->Belt.Array.map(story => ) + ->Array.map(story => ) ->React.array} // change-line diff --git a/rescript-relay-documentation/docs/unions.md b/rescript-relay-documentation/docs/unions.md index 36538283..247ba4da 100644 --- a/rescript-relay-documentation/docs/unions.md +++ b/rescript-relay-documentation/docs/unions.md @@ -58,7 +58,7 @@ module Query = %relay( @react.component let make = (~roomId) => { - let queryData = Query.use(~variables={roomId: roomId}, ()) + let queryData = Query.use(~variables={roomId: roomId}) switch queryData.roomOwner { | Some(roomOwner) => diff --git a/rescript-relay-documentation/docs/using-fragments.md b/rescript-relay-documentation/docs/using-fragments.md index 044e0734..e58bb690 100644 --- a/rescript-relay-documentation/docs/using-fragments.md +++ b/rescript-relay-documentation/docs/using-fragments.md @@ -117,8 +117,7 @@ let make = (~userId) => { let queryData = Query.use( ~variables={ userId: userId, - }, - (), + } ) switch queryData.userById { @@ -237,7 +236,6 @@ let logPurchase = user => { SomeLoggingService.log( ~customerId=userId.customerId, ~someOtherMetaDataProp=userId.someOtherMetaDataProp, - (), ) } diff --git a/rescript-relay-documentation/docs/variables.md b/rescript-relay-documentation/docs/variables.md index e54c4efc..20d06847 100644 --- a/rescript-relay-documentation/docs/variables.md +++ b/rescript-relay-documentation/docs/variables.md @@ -26,10 +26,10 @@ module Mutation = %relay(` `) // All optional variables in this operation can now be `null`, which will be preserved and sent to your server. -Mutation.commitMutation(~environment=RelayEnvironment.environment, ~variables={avatarUrl: Js.null}, ()) +Mutation.commitMutation(~environment=RelayEnvironment.environment, ~variables={avatarUrl: Null}) // Or if you want to send a value: -Mutation.commitMutation(~environment=RelayEnvironment.environment, ~variables={avatarUrl: Js.Null.return("some-avatar-url")}, ()) +Mutation.commitMutation(~environment=RelayEnvironment.environment, ~variables={avatarUrl: Value("some-avatar-url")}) ``` This works for: