rescript-relay 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # master
2
2
 
3
+ # 3.4.0
4
+
5
+ - Add support for `@exhaustive` - a directive to trigger exhaustiveness checks for unions at the GraphQL operation level.
6
+ - **BREAKING** Drop `__typename` in inline records, since that conflicts with using `@tag("__typename")` in ReScript v12 and is not necessary since `__typename` is set automatically via `@tag`.
7
+
8
+ # 3.3.0
9
+
10
+ - Add support for top level `@catch` on fragments on unions.
11
+ - Add parameter `excludedIds: array<dataId>` to `invalidateRecordsByIds` to allow excluding a list of connection IDs from invalidation.
12
+ - **BREAKING:** `operation.text` and `operation.id` are now nullable, which better reflects what values they can actually have in runtime.
13
+ - fix bug where custom scalars would error when set to null in refetch variables.
14
+
3
15
  # 3.2.0
4
16
 
5
17
  - Add support for the new Relay `@catch` directive. https://github.com/zth/rescript-relay/pull/549
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rescript-relay",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "main": "src/RescriptRelay.res",
5
5
  "license": "MIT",
6
6
  "author": "Gabriel Nordeborn",
package/ppx-linux CHANGED
Binary file
package/ppx-macos-arm64 CHANGED
Binary file
package/ppx-macos-latest CHANGED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -283,12 +283,16 @@ function findAllConnectionIds(environment, connectionKey, parentId) {
283
283
  return ids;
284
284
  }
285
285
 
286
- function invalidateAllOfConnection(environment, connectionKey, parentId) {
286
+ function invalidateAllOfConnection(environment, connectionKey, parentId, excludedIdsOpt) {
287
+ var excludedIds = excludedIdsOpt !== undefined ? excludedIdsOpt : [];
287
288
  RelayRuntime.commitLocalUpdate(environment, (function (store) {
288
289
  findAllConnectionIds(environment, connectionKey, parentId).forEach(function (dataId) {
289
- Belt_Option.forEach(Caml_option.nullable_to_opt(store.get(dataId)), (function (r) {
290
- r.invalidateRecord();
291
- }));
290
+ if (!excludedIds.includes(dataId)) {
291
+ return Belt_Option.forEach(Caml_option.nullable_to_opt(store.get(dataId)), (function (r) {
292
+ r.invalidateRecord();
293
+ }));
294
+ }
295
+
292
296
  });
293
297
  }));
294
298
  }
@@ -534,8 +534,8 @@ module Network = {
534
534
  type operationMetadata = {codesplits?: array<codesplitsMetadata>}
535
535
 
536
536
  type operation = {
537
- id: string,
538
- text: string,
537
+ id: Js.Nullable.t<string>,
538
+ text: Js.Nullable.t<string>,
539
539
  name: string,
540
540
  operationKind: string,
541
541
  metadata: Js.Nullable.t<operationMetadata>,
@@ -796,14 +796,21 @@ module Environment = {
796
796
  ids
797
797
  }
798
798
 
799
- let invalidateAllOfConnection = (environment: t, ~connectionKey: string, ~parentId: dataId) => {
799
+ let invalidateAllOfConnection = (
800
+ environment: t,
801
+ ~connectionKey: string,
802
+ ~parentId: dataId,
803
+ ~excludedIds=[],
804
+ ) => {
800
805
  environment->commitLocalUpdate(~updater=store => {
801
806
  environment
802
807
  ->findAllConnectionIds(~connectionKey, ~parentId)
803
808
  ->Js.Array2.forEach(dataId => {
804
- store
805
- ->RecordSourceSelectorProxy.get(~dataId)
806
- ->Belt.Option.forEach(r => r->RecordProxy.invalidateRecord)
809
+ if !(excludedIds->Js.Array2.includes(dataId)) {
810
+ store
811
+ ->RecordSourceSelectorProxy.get(~dataId)
812
+ ->Belt.Option.forEach(r => r->RecordProxy.invalidateRecord)
813
+ }
807
814
  })
808
815
  })
809
816
  }
@@ -94,12 +94,56 @@ external makeUploadables: Js.Dict.t<'file> => uploadables = "%identity"
94
94
  /**Unwraps `uploadables` into a Js.Dict.t with your expected file type, so you can use that dict to attach the provided files to your request.*/
95
95
  external unwrapUploadables: uploadables => Js.Dict.t<'file> = "%identity"
96
96
 
97
- /**This generates a `dataId` for use on the _client_ side. However, this is farily low level, and what you're probably really looking for is `generateUniqueClientID` that'll let you generate a new, unique `dataId` that you can use for client side only records (like when doing optimistic updates).*/
97
+ /**
98
+ Generates a client-side `dataId` derived from an existing record.
99
+
100
+ This is a low-level function for creating deterministic client IDs. For most use cases,
101
+ prefer `generateUniqueClientID` which creates globally unique identifiers.
102
+
103
+ ## Parameters
104
+ - `dataId`: The base record ID to derive from
105
+ - `storageKey`: A unique key for this derived record
106
+ - `index`: Optional index for array-like derived records
107
+
108
+ ## Examples
109
+
110
+ ```rescript
111
+ // Create a client ID for a cached query result
112
+ let derivedId = RescriptRelay.generateClientID(
113
+ ~dataId=user.__id,
114
+ ~storageKey="cached_search_results",
115
+ )
116
+ ```
117
+ */
98
118
  @module("relay-runtime")
99
119
  external generateClientID: (~dataId: dataId, ~storageKey: string, ~index: int=?) => dataId =
100
120
  "generateClientID"
101
121
 
102
- /**This generates a unique `dataId` that's safe to use on the _client_ side. Useful when doing optimistic updates and you need to create IDs that the optimistic update can use.*/
122
+ /**
123
+ Generates a globally unique client-side `dataId`.
124
+
125
+ Creates a new unique identifier safe for client-side records. Primarily used for
126
+ optimistic updates where you need temporary IDs before server confirmation.
127
+
128
+ ## Examples
129
+
130
+ ```rescript
131
+ // Use in optimistic response
132
+ mutate(
133
+ ~variables={...},
134
+ ~optimisticResponse={
135
+ userCreated: Some({
136
+ user: {
137
+ id: RescriptRelay.generateUniqueClientID(),
138
+ name: "New User",
139
+ __typename: #User,
140
+ }
141
+ })
142
+ }
143
+ )
144
+
145
+ ```
146
+ */
103
147
  @module("relay-runtime")
104
148
  external generateUniqueClientID: unit => dataId = "generateUniqueClientID"
105
149
 
@@ -171,15 +215,70 @@ module RecordProxy: {
171
215
  /**Read the following section on working with the Relay store: https://relay.dev/docs/en/relay-store*/
172
216
  type t
173
217
 
174
- /**Copies all fields from one `RecordProxy` to another.*/
218
+ /**
219
+ Copies all fields from a source record to the current record.
220
+
221
+ Performs a shallow copy of all field values from the source record to the target record.
222
+ Useful for duplicating record data or applying bulk updates.
223
+
224
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
225
+
226
+ ## Parameters
227
+ - `sourceRecord`: The record to copy fields from
228
+
229
+ ## Examples
230
+
231
+ ```rescript
232
+ // Copy from newUser to existing user record
233
+ userRecord->RescriptRelay.RecordProxy.copyFieldsFrom(~sourceRecord=newUser)
234
+ ```
235
+ */
175
236
  @send
176
237
  external copyFieldsFrom: (t, ~sourceRecord: t) => unit = "copyFieldsFrom"
177
238
 
178
- /**Gets the `dataId` for a particular record.*/
239
+ /**
240
+ Gets the unique identifier for this record.
241
+
242
+ Returns the `dataId` that Relay uses to identify this record in the store.
243
+ Every record in Relay has a unique `dataId`.
244
+
245
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
246
+
247
+ ## Examples
248
+
249
+ ```rescript
250
+ let userId = userRecord->RescriptRelay.RecordProxy.getDataId
251
+ Console.log("User ID: " ++ RescriptRelay.dataIdToString(userId))
252
+ ```
253
+ */
179
254
  @send
180
255
  external getDataId: t => dataId = "getDataID"
181
256
 
182
- /**Gets a single linked record. A linked record is another object in the store, and not a scalar field like an int or float.*/
257
+ /**
258
+ Gets a linked record (object) field.
259
+
260
+ Retrieves another record that is linked from this record. Returns `None` if
261
+ the field doesn't exist or is null.
262
+
263
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
264
+
265
+ ## Parameters
266
+ - `name`: The field name to retrieve
267
+ - `arguments`: Optional arguments for parameterized fields
268
+
269
+ ## Examples
270
+
271
+ ```rescript
272
+ // Get user's profile
273
+ let profile = userRecord->RescriptRelay.RecordProxy.getLinkedRecord(~name="profile")
274
+
275
+ // Get user's post with specific ID
276
+ let post = userRecord->RescriptRelay.RecordProxy.getLinkedRecord(
277
+ ~name="post",
278
+ ~arguments=RescriptRelay.makeArguments({"id": postId})
279
+ )
280
+ ```
281
+ */
183
282
  @send
184
283
  @return(nullable)
185
284
  external getLinkedRecord: (t, ~name: string, ~arguments: arguments=?) => option<t> =
@@ -258,12 +357,56 @@ module RecordProxy: {
258
357
  ~arguments: arguments=?,
259
358
  ) => option<array<option<bool>>> = "getValue"
260
359
 
261
- /**Sets a `RecordProxy.t` as the linked record for a particular field.*/
360
+ /**
361
+ Sets a linked record for a field.
362
+
363
+ Links another record to this record at the specified field. The linked record
364
+ must already exist in the store.
365
+
366
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
367
+
368
+ ## Parameters
369
+ - `record`: The record to link
370
+ - `name`: The field name to set
371
+ - `arguments`: Optional arguments for parameterized fields
372
+
373
+ ## Examples
374
+
375
+ ```rescript
376
+ // Link a profile to a user
377
+ let _ = userRecord->RescriptRelay.RecordProxy.setLinkedRecord(
378
+ ~record=profileRecord,
379
+ ~name="profile"
380
+ )
381
+ ```
382
+ */
262
383
  @send
263
384
  external setLinkedRecord: (t, ~record: t, ~name: string, ~arguments: arguments=?) => t =
264
385
  "setLinkedRecord"
265
386
 
266
- /**Sets an array of `RecordProxy.t` as the linked records for a particular field.*/
387
+ /**
388
+ Sets an array of linked records for a field.
389
+
390
+ Links multiple records to this record at the specified field. Use `None` for
391
+ null entries in the array.
392
+
393
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
394
+
395
+ ## Parameters
396
+ - `records`: Array of records to link (with optional null entries)
397
+ - `name`: The field name to set
398
+ - `arguments`: Optional arguments for parameterized fields
399
+
400
+ ## Examples
401
+
402
+ ```rescript
403
+ // Set user's posts
404
+ let _ = userRecord->RescriptRelay.RecordProxy.setLinkedRecords(
405
+ ~records=[Some(post1), None, Some(post3)],
406
+ ~name="posts"
407
+ )
408
+ ```
409
+ */
267
410
  @send
268
411
  external setLinkedRecords: (
269
412
  t,
@@ -389,15 +532,78 @@ module RecordSourceSelectorProxy: {
389
532
  @send
390
533
  external batchLiveStateUpdates: (t, unit => unit) => unit = "batchLiveStateUpdates"
391
534
 
392
- /**Creates a new `RecordProxy`.*/
535
+ /**
536
+ Creates a new record in the store.
537
+
538
+ Creates a new record with the specified ID and type. The record will be empty
539
+ initially - use `RecordProxy` methods to populate its fields.
540
+
541
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
542
+
543
+ ## Parameters
544
+ - `dataId`: Unique identifier for the new record
545
+ - `typeName`: GraphQL type name for the record
546
+
547
+ ## Examples
548
+
549
+ ```rescript
550
+ // Create optimistic user record
551
+ let newUser = store->RescriptRelay.RecordSourceSelectorProxy.create(
552
+ ~dataId=RescriptRelay.generateUniqueClientID(),
553
+ ~typeName="User"
554
+ )
555
+
556
+ let _ = newUser->RescriptRelay.RecordProxy.setValueString(~value="John Doe", ~name="name")
557
+ ```
558
+ */
393
559
  @send
394
560
  external create: (t, ~dataId: dataId, ~typeName: string) => RecordProxy.t = "create"
395
561
 
396
- /**Deletes the `RecordProxy` with the provided `dataId`.*/
562
+ /**
563
+ Deletes a record from the store.
564
+
565
+ Removes the record with the specified ID from the store. Any references to
566
+ this record from other records will become null.
567
+
568
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
569
+
570
+ ## Parameters
571
+ - `dataId`: The ID of the record to delete
572
+
573
+ ## Examples
574
+
575
+ ```rescript
576
+ // Delete a user record
577
+ store->RescriptRelay.RecordSourceSelectorProxy.delete(~dataId=userId)
578
+ ```
579
+ */
397
580
  @send
398
581
  external delete: (t, ~dataId: dataId) => unit = "delete"
399
582
 
400
- /**Returns the `RecordProxy` with the provided `dataId`, if it exists.*/
583
+ /**
584
+ Gets a record from the store by ID.
585
+
586
+ Retrieves an existing record from the store. Returns `None` if the record
587
+ doesn't exist.
588
+
589
+ ⚠️ **Note**: This is a low-level, non-type-safe API. Use with caution and prefer higher-level operations when possible.
590
+
591
+ ## Parameters
592
+ - `dataId`: The ID of the record to retrieve
593
+
594
+ ## Examples
595
+
596
+ ```rescript
597
+ switch store->RescriptRelay.RecordSourceSelectorProxy.get(~dataId=userId) {
598
+ | Some(userRecord) =>
599
+ // Work with the user record
600
+ let _ = userRecord->RescriptRelay.RecordProxy.setValueBool(~value=true, ~name="isActive")
601
+ | None =>
602
+ // Record doesn't exist
603
+ ()
604
+ }
605
+ ```
606
+ */
401
607
  @send
402
608
  @return(nullable)
403
609
  external get: (t, ~dataId: dataId) => option<RecordProxy.t> = "get"
@@ -523,9 +729,37 @@ module MissingFieldHandler: {
523
729
  ) => t
524
730
  }
525
731
 
526
- /**Read the Relay docs section on [ConnectionHandler](https://relay.dev/docs/en/relay-store#connectionhandler)*/
732
+ /**
733
+ Utilities for working with Relay connections.
734
+
735
+ Connections are Relay's way of handling paginated lists. These utilities help you
736
+ manipulate connection data in the store, such as adding/removing edges and getting
737
+ connection records.
738
+
739
+ Read the [Relay ConnectionHandler docs](https://relay.dev/docs/en/relay-store#connectionhandler) for more details.
740
+ */
527
741
  module ConnectionHandler: {
528
- /**For a `RecordProxy`, returns the `RecordProxy` that is at the connection config provided.*/
742
+ /**
743
+ Gets a connection record from a parent record.
744
+
745
+ Retrieves the connection record for a specific connection key and optional filters.
746
+ Returns `None` if the connection doesn't exist.
747
+
748
+ ## Parameters
749
+ - `record`: The parent record containing the connection
750
+ - `key`: The connection key (from `@connection(key: "...")`)
751
+ - `filters`: Optional filter arguments used in the connection
752
+
753
+ ## Examples
754
+
755
+ ```rescript
756
+ // Get user's friends connection
757
+ let friendsConnection = RescriptRelay.ConnectionHandler.getConnection(
758
+ ~record=userRecord,
759
+ ~key=UserFriends_user_graphql.connectionKey,
760
+ )
761
+ ```
762
+ */
529
763
  @module("relay-runtime")
530
764
  @scope("ConnectionHandler")
531
765
  @return(nullable)
@@ -535,7 +769,32 @@ module ConnectionHandler: {
535
769
  ~filters: arguments=?,
536
770
  ) => option<RecordProxy.t> = "getConnection"
537
771
 
538
- /**Creates an edge for a particular connection.*/
772
+ /**
773
+ Creates an edge record for a connection.
774
+
775
+ Creates a new edge that can be inserted into a connection. The edge wraps
776
+ a node and provides cursor information for pagination.
777
+
778
+ 💡 **Tip**: For most cases, prefer using declarative directives like `@appendNode` or `@prependNode` in your mutations instead of manually managing edges.
779
+
780
+ ## Parameters
781
+ - `store`: The store to create the edge in
782
+ - `connection`: The connection this edge belongs to
783
+ - `node`: The node (record) to wrap in this edge
784
+ - `edgeType`: The GraphQL type name for the edge
785
+
786
+ ## Examples
787
+
788
+ ```rescript
789
+ // Create edge for new friend
790
+ let newEdge = RescriptRelay.ConnectionHandler.createEdge(
791
+ ~store,
792
+ ~connection=friendsConnection,
793
+ ~node=newFriendRecord,
794
+ ~edgeType="UserEdge"
795
+ )
796
+ ```
797
+ */
539
798
  @module("relay-runtime")
540
799
  @scope("ConnectionHandler")
541
800
  external createEdge: (
@@ -545,7 +804,36 @@ module ConnectionHandler: {
545
804
  ~edgeType: string,
546
805
  ) => RecordProxy.t = "createEdge"
547
806
 
548
- /**Inserts an edge into a connection _before_ the provided cursor. If no cursor is provided, it inserts the edge at the start of the connection list.*/
807
+ /**
808
+ Inserts an edge before a specific cursor or at the beginning.
809
+
810
+ Adds an edge to the connection before the specified cursor position.
811
+ If no cursor is provided, the edge is inserted at the start of the list.
812
+
813
+ 💡 **Tip**: For most cases, prefer using declarative directives like `@prependEdge` in your mutations instead of manually inserting edges.
814
+
815
+ ## Parameters
816
+ - `connection`: The connection to insert into
817
+ - `newEdge`: The edge to insert
818
+ - `cursor`: Optional cursor to insert before
819
+
820
+ ## Examples
821
+
822
+ ```rescript
823
+ // Insert at beginning
824
+ RescriptRelay.ConnectionHandler.insertEdgeBefore(
825
+ ~connection=friendsConnection,
826
+ ~newEdge=friendEdge
827
+ )
828
+
829
+ // Insert before specific cursor
830
+ RescriptRelay.ConnectionHandler.insertEdgeBefore(
831
+ ~connection=friendsConnection,
832
+ ~newEdge=friendEdge,
833
+ ~cursor="cursor123"
834
+ )
835
+ ```
836
+ */
549
837
  @module("relay-runtime")
550
838
  @scope("ConnectionHandler")
551
839
  external insertEdgeBefore: (
@@ -554,7 +842,29 @@ module ConnectionHandler: {
554
842
  ~cursor: string=?,
555
843
  ) => unit = "insertEdgeBefore"
556
844
 
557
- /**Inserts an edge into a connection _after_ the provided cursor. If no cursor is provided, it inserts the edge at the end of the connection list.*/
845
+ /**
846
+ Inserts an edge after a specific cursor or at the end.
847
+
848
+ Adds an edge to the connection after the specified cursor position.
849
+ If no cursor is provided, the edge is inserted at the end of the list.
850
+
851
+ 💡 **Tip**: For most cases, prefer using declarative directives like `@appendEdge` in your mutations instead of manually inserting edges.
852
+
853
+ ## Parameters
854
+ - `connection`: The connection to insert into
855
+ - `newEdge`: The edge to insert
856
+ - `cursor`: Optional cursor to insert after
857
+
858
+ ## Examples
859
+
860
+ ```rescript
861
+ // Insert at end
862
+ RescriptRelay.ConnectionHandler.insertEdgeAfter(
863
+ ~connection=friendsConnection,
864
+ ~newEdge=friendEdge
865
+ )
866
+ ```
867
+ */
558
868
  @module("relay-runtime")
559
869
  @scope("ConnectionHandler")
560
870
  external insertEdgeAfter: (
@@ -563,12 +873,59 @@ module ConnectionHandler: {
563
873
  ~cursor: string=?,
564
874
  ) => unit = "insertEdgeAfter"
565
875
 
566
- /**Deletes any edge from the connection where the node of the edge has the provided `dataId`. Please not that this _will not_ remove the actual node from the store. Use `RecordSourceSelectorProxy.delete` for that.*/
876
+ /**
877
+ Removes a node from a connection by its ID.
878
+
879
+ Deletes any edge from the connection where the edge's node has the specified ID.
880
+ Note: This only removes the edge, not the actual node record from the store.
881
+
882
+ 💡 **Tip**: For most cases, prefer using declarative directives like `@deleteEdge` in your mutations instead of manually removing edges.
883
+
884
+ ## Parameters
885
+ - `connection`: The connection to remove from
886
+ - `nodeId`: The ID of the node to remove
887
+
888
+ ## Examples
889
+
890
+ ```rescript
891
+ // Remove friend from connection
892
+ RescriptRelay.ConnectionHandler.deleteNode(
893
+ ~connection=friendsConnection,
894
+ ~nodeId=friendId
895
+ )
896
+ ```
897
+ */
567
898
  @module("relay-runtime")
568
899
  @scope("ConnectionHandler")
569
900
  external deleteNode: (~connection: RecordProxy.t, ~nodeId: dataId) => unit = "deleteNode"
570
901
 
571
- /**Constructs a `dataId` targeting a specific connection at a specific parent. Note that the generated module for every fragment with a `@connection` will have a `<moduleName>.Utils.connectionKey` representing the connection key of that particular `@connection`, that you should use with this.*/
902
+ /**
903
+ Generates a connection's unique data ID.
904
+
905
+ Constructs the internal ID that Relay uses to identify a specific connection
906
+ on a specific parent with specific filters.
907
+
908
+ 💡 **Tip**: For connections with arguments, the generated fragment module includes a type-safe `getConnectionId` function. For example, `UserPosts_user_graphql.getConnectionId(~status="PUBLISHED")`.
909
+
910
+ ## Parameters
911
+ - Parent record's data ID
912
+ - Connection key string
913
+ - Filter arguments object
914
+
915
+ ## Examples
916
+
917
+ ```rescript
918
+ // Get connection ID for user's filtered posts
919
+ let connectionId = RescriptRelay.ConnectionHandler.getConnectionID(
920
+ userId,
921
+ UserPosts_user_graphql.connectionKey,
922
+ {"status": "PUBLISHED"}
923
+ )
924
+
925
+ // A type-safe version is also available for each fragment defined. Prefer using that.
926
+ let connectionId = UserPosts_user_graphql.getConnectionId(~status=PUBLISHED)
927
+ ```
928
+ */
572
929
  @module("relay-runtime")
573
930
  @scope("ConnectionHandler")
574
931
  external getConnectionID: (dataId, string, 'filters) => dataId = "getConnectionID"
@@ -630,28 +987,73 @@ module Observable: {
630
987
  /**Ignore this subscription.*/ external ignoreSubscription: subscription => unit = "%ignore"
631
988
  }
632
989
 
633
- /**Represents the network layer.*/
990
+ /**
991
+ Network layer configuration for Relay.
992
+
993
+ The network layer defines how Relay makes requests to your GraphQL server.
994
+ You must provide fetch and optionally subscription functions to handle
995
+ queries, mutations, and subscriptions.
996
+ */
634
997
  module Network: {
635
998
  type codesplitsMetadata = (string, unit => unit)
636
999
 
637
1000
  type operationMetadata = {codesplits?: array<codesplitsMetadata>}
638
1001
 
639
- /**The type representing an instantiated `NetworkLayer`.*/
1002
+ /**The type representing an instantiated network layer.*/
640
1003
  type t
641
1004
 
642
- /**The operation fed to the `NetworkLayer` when Relay wants to make a request. Please note that if you're using persisted queries, `id` will exist but `text` won't, and vice versa when not using persisted queries.*/
1005
+ /**
1006
+ Information about a GraphQL operation being executed.
1007
+
1008
+ Contains the operation details that your fetch function will receive.
1009
+ For persisted queries, `id` exists but `text` is empty. For regular queries,
1010
+ `text` contains the query string but `id` is empty.
1011
+
1012
+ ## Fields
1013
+ - `id`: Persisted query ID (if using persisted queries)
1014
+ - `text`: GraphQL query text (if not using persisted queries)
1015
+ - `name`: Operation name
1016
+ - `operationKind`: "query", "mutation", or "subscription"
1017
+ - `metadata`: Optional operation metadata
1018
+ */
643
1019
  type operation = {
644
- id: string,
645
- text: string,
1020
+ /** The operation ID. Set if persisted queries are enabled, otherwise not set. */
1021
+ id: Js.Nullable.t<string>,
1022
+ /** The operation text. Not set for persisted queries, or if this is a client-only query that will not make a network request. */
1023
+ text: Js.Nullable.t<string>,
1024
+ /** The operation name. */
646
1025
  name: string,
1026
+ /** The operation kind. */
647
1027
  operationKind: string,
1028
+ /** Optional operation metadata. */
648
1029
  metadata: Js.Nullable.t<operationMetadata>,
649
1030
  }
650
1031
 
651
- /**The shape of the function Relay expects for creating a subscription.*/
1032
+ /**
1033
+ Function signature for handling GraphQL subscriptions.
1034
+
1035
+ ## Parameters
1036
+ - `operation`: The subscription operation details
1037
+ - `variables`: JSON variables for the subscription
1038
+ - `cacheConfig`: Cache configuration options
1039
+
1040
+ ## Returns
1041
+ Observable that emits subscription data over time
1042
+ */
652
1043
  type subscribeFn = (operation, Js.Json.t, cacheConfig) => Observable.t<Js.Json.t>
653
1044
 
654
- /**The shape of the function responsible for fetching data if you want to return a promise rather than an `Observable`.*/
1045
+ /**
1046
+ Function signature for fetching data using promises.
1047
+
1048
+ ## Parameters
1049
+ - `operation`: The operation details
1050
+ - `variables`: JSON variables for the operation
1051
+ - `cacheConfig`: Cache configuration options
1052
+ - `uploadables`: Optional file uploads
1053
+
1054
+ ## Returns
1055
+ Promise that resolves to the GraphQL response
1056
+ */
655
1057
  type fetchFunctionPromise = (
656
1058
  operation,
657
1059
  Js.Json.t,
@@ -659,7 +1061,18 @@ module Network: {
659
1061
  Js.Nullable.t<uploadables>,
660
1062
  ) => Js.Promise.t<Js.Json.t>
661
1063
 
662
- /**The shape of the function responsible for fetching data if you want to return an `Observable`.*/
1064
+ /**
1065
+ Function signature for fetching data using observables.
1066
+
1067
+ ## Parameters
1068
+ - `operation`: The operation details
1069
+ - `variables`: JSON variables for the operation
1070
+ - `cacheConfig`: Cache configuration options
1071
+ - `uploadables`: Optional file uploads
1072
+
1073
+ ## Returns
1074
+ Observable that emits the GraphQL response
1075
+ */
663
1076
  type fetchFunctionObservable = (
664
1077
  operation,
665
1078
  Js.Json.t,
@@ -667,7 +1080,16 @@ module Network: {
667
1080
  Js.Nullable.t<uploadables>,
668
1081
  ) => Observable.t<Js.Json.t>
669
1082
 
670
- /**Create a new `NetworkLayer` using a fetch function that returns a promise.*/
1083
+ /**
1084
+ Creates a network layer using a promise-based fetch function.
1085
+
1086
+ Most common way to create a network layer. Your fetch function should
1087
+ make HTTP requests to your GraphQL endpoint and return promises.
1088
+
1089
+ ## Parameters
1090
+ - `fetchFunction`: Function that returns promises for GraphQL requests
1091
+ - `subscriptionFunction`: Optional function for handling subscriptions
1092
+ */
671
1093
  @module("relay-runtime")
672
1094
  @scope("Network")
673
1095
  external makePromiseBased: (
@@ -675,7 +1097,16 @@ module Network: {
675
1097
  ~subscriptionFunction: subscribeFn=?,
676
1098
  ) => t = "create"
677
1099
 
678
- /**Create a new `NetworkLayer` using a fetch function that returns an `Observable`.*/
1100
+ /**
1101
+ Creates a network layer using an observable-based fetch function.
1102
+
1103
+ Use this when you need more control over the request lifecycle or want to
1104
+ handle streaming responses like `@defer` and `@stream`.
1105
+
1106
+ ## Parameters
1107
+ - `observableFunction`: Function that returns observables for GraphQL requests
1108
+ - `subscriptionFunction`: Optional function for handling subscriptions
1109
+ */
679
1110
  @module("relay-runtime")
680
1111
  @scope("Network")
681
1112
  external makeObservableBased: (
@@ -683,62 +1114,200 @@ module Network: {
683
1114
  ~subscriptionFunction: subscribeFn=?,
684
1115
  ) => t = "create"
685
1116
 
1117
+ /**
1118
+ Preloads resources based on operation response.
1119
+
1120
+ Internal function for resource preloading. Used by Relay's code splitting
1121
+ and resource preloading features.
1122
+ */
686
1123
  let preloadResources: (~operation: operation, ~variables: Js.Json.t, ~response: Js.Json.t) => unit
687
1124
  }
688
1125
 
689
- /**RecordSource is the source of records used by the store. Can be initiated with or without prior records; eg. hydrating the store with prior data.*/
1126
+ /**
1127
+ The RecordSource - storage for normalized GraphQL records.
1128
+
1129
+ RecordSource is the underlying storage mechanism that holds normalized GraphQL
1130
+ records. It can be initialized empty or with existing data for hydration scenarios
1131
+ like SSR. The store uses a RecordSource to persist and retrieve cached data.
1132
+ */
690
1133
  module RecordSource: {
691
- /**The type representing an instantiated `RecordSource`.*/
1134
+ /**The type representing a RecordSource instance.*/
692
1135
  type t
693
1136
 
694
- /**Create a new `RecordSource`. Here's where you pass an existing `recordSourceRecords` if you have existing records you want to hydrate the store with, when doing SSR or similar.*/
1137
+ /**
1138
+ Creates a new RecordSource.
1139
+
1140
+ Can be initialized empty or with existing record data for hydration.
1141
+ When doing SSR, you'll typically create an empty RecordSource on the server,
1142
+ populate it with data, serialize it, and then recreate it on the client.
1143
+
1144
+ ## Parameters
1145
+ - `records`: Optional existing records to initialize with
1146
+
1147
+ ## Examples
1148
+
1149
+ ```rescript
1150
+ // Create empty RecordSource
1151
+ let source = RescriptRelay.RecordSource.make()
1152
+
1153
+ // Create RecordSource with existing data (e.g., from SSR)
1154
+ let hydratedSource = RescriptRelay.RecordSource.make(
1155
+ ~records=serverSideRecords
1156
+ )
1157
+ ```
1158
+ */
695
1159
  @module("relay-runtime")
696
1160
  @new
697
1161
  external make: (~records: recordSourceRecords=?) => t = "RecordSource"
698
1162
 
699
- /**Serializes the `RecordSource` into `recordSourceRecords` that you can use to rehydrate another store. Typically used for SSR.*/
1163
+ /**
1164
+ Serializes the RecordSource to JSON.
1165
+
1166
+ Converts all records in the source to a JSON representation that can be
1167
+ transmitted or stored. Commonly used for SSR to send server-side cached
1168
+ data to the client.
1169
+
1170
+ ## Returns
1171
+ JSON object containing all normalized records
1172
+
1173
+ ## Examples
1174
+
1175
+ ```rescript
1176
+ // Serialize for SSR
1177
+ let serverRecords = recordSource->RescriptRelay.RecordSource.toJSON
1178
+
1179
+ // Send to client or store in localStorage
1180
+ let serialized = Js.Json.stringify(serverRecords)
1181
+ ```
1182
+ */
700
1183
  @send
701
1184
  external toJSON: t => recordSourceRecords = "toJSON"
702
1185
  }
703
1186
 
704
- /**The actual store module, with configuration for the store.*/
1187
+ /**
1188
+ The Relay Store - manages normalized GraphQL data caching.
1189
+
1190
+ The Store handles data normalization, caching, garbage collection, and provides
1191
+ interfaces for reading and writing data. It works with a RecordSource to persist
1192
+ the actual record data.
1193
+ */
705
1194
  module Store: {
706
- /**The type representing an instantiated `Store`.*/
1195
+ /**The type representing a Relay store instance.*/
707
1196
  type t
708
1197
 
709
- /**Creates a new `Store`.*/
1198
+ /**
1199
+ Creates a new standard Relay store.
1200
+
1201
+ The store manages normalized data and provides caching with configurable
1202
+ garbage collection and TTL settings.
1203
+
1204
+ ## Parameters
1205
+ - `source`: RecordSource containing the initial data
1206
+ - `gcReleaseBufferSize`: Number of queries to keep cached (default: 10)
1207
+ - `queryCacheExpirationTime`: TTL in milliseconds for cached queries (default: no TTL)
1208
+
1209
+ ## Examples
1210
+
1211
+ ```rescript
1212
+ let store = RescriptRelay.Store.make(
1213
+ ~source=RescriptRelay.RecordSource.make(),
1214
+ ~gcReleaseBufferSize=20, // Keep 20 queries cached
1215
+ ~queryCacheExpirationTime=5 * 60 * 1000, // 5 minute TTL
1216
+ )
1217
+ ```
1218
+ */
710
1219
  let make: (
711
1220
  ~source: RecordSource.t,
712
- ~gcReleaseBufferSize: /* `gcReleaseBufferSize` controls how many queries are allowed to be cached by default. Increase this to increase the size of the cache. */
713
- int=?,
1221
+ ~gcReleaseBufferSize: int=?,
714
1222
  ~queryCacheExpirationTime: int=?,
715
- ) => /* `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. */
716
- t
1223
+ ) => t
1224
+
1225
+ /**
1226
+ Creates a new live store with real-time capabilities.
1227
+
1228
+ Similar to the standard store but with enhanced support for live queries
1229
+ and real-time data updates. Only needed if you're using Relay Resolvers.
1230
+
1231
+ ℹ️ **Note**: Use this only when you need Relay Resolvers. For most applications, the standard `make` function is sufficient.
717
1232
 
718
- /**Creates a new `LiveStore`.*/
1233
+ ## Parameters
1234
+ - `source`: RecordSource containing the initial data
1235
+ - `gcReleaseBufferSize`: Number of queries to keep cached (default: 10)
1236
+ - `queryCacheExpirationTime`: TTL in milliseconds for cached queries (default: no TTL)
1237
+
1238
+ ## Examples
1239
+
1240
+ ```rescript
1241
+ let liveStore = RescriptRelay.Store.makeLiveStore(
1242
+ ~source=RescriptRelay.RecordSource.make(),
1243
+ ~gcReleaseBufferSize=15,
1244
+ )
1245
+ ```
1246
+ */
719
1247
  let makeLiveStore: (
720
1248
  ~source: RecordSource.t,
721
- ~gcReleaseBufferSize: /* `gcReleaseBufferSize` controls how many queries are allowed to be cached by default. Increase this to increase the size of the cache. */
722
- int=?,
1249
+ ~gcReleaseBufferSize: int=?,
723
1250
  ~queryCacheExpirationTime: int=?,
724
- ) => /* `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. */
725
- t
1251
+ ) => t
726
1252
 
1253
+ /**Internal CommonJS version of makeLiveStore. Use `makeLiveStore` instead.*/
727
1254
  let _makeLiveStoreCjs: (
728
1255
  ~source: RecordSource.t,
729
1256
  ~gcReleaseBufferSize: int=?,
730
1257
  ~queryCacheExpirationTime: int=?,
731
1258
  ) => t
732
1259
 
733
- /**Gets the `RecordSource` for this `Store`.*/
1260
+ /**
1261
+ Gets the RecordSource from this store.
1262
+
1263
+ Provides access to the underlying record source for advanced operations
1264
+ like serialization or direct record access.
1265
+
1266
+ ## Examples
1267
+
1268
+ ```rescript
1269
+ let source = store->RescriptRelay.Store.getSource
1270
+ let serialized = source->RescriptRelay.RecordSource.toJSON
1271
+ ```
1272
+ */
734
1273
  @send
735
1274
  external getSource: t => RecordSource.t = "getSource"
736
1275
 
737
- /**Publishes _new_ records to this store. This is useful in particular with frameworks like Next.js where routes could preload data needed and then serialize that (using `RecordSource.toJSON`) and send it over the wire, but you already have a store instantiated client side. This will then allow you to publish those records into your existing store.*/
1276
+ /**
1277
+ Publishes new records to the store.
1278
+
1279
+ Merges new record data into the existing store. Particularly useful for
1280
+ SSR scenarios where you need to hydrate client-side stores with server data.
1281
+
1282
+ ## Parameters
1283
+ - `source`: RecordSource containing new records to publish
1284
+
1285
+ ## Examples
1286
+
1287
+ ```rescript
1288
+ // Hydrate client store with server data
1289
+ let serverRecords = RescriptRelay.RecordSource.make(~records=serverData)
1290
+ store->RescriptRelay.Store.publish(serverRecords)
1291
+ ```
1292
+ */
738
1293
  @send
739
1294
  external publish: (t, RecordSource.t) => unit = "publish"
740
1295
 
741
- /**Informes the store to stop its normal garbage collection processes. This prevents data being lost between calling relay's `fetchQuery` any serialization process (eg: toJSON)*/
1296
+ /**
1297
+ Temporarily disables garbage collection.
1298
+
1299
+ Prevents the store from cleaning up cached data. Useful when you need to
1300
+ ensure data persistence during operations like serialization.
1301
+
1302
+ ## Examples
1303
+
1304
+ ```rescript
1305
+ // Hold GC during serialization
1306
+ store->RescriptRelay.Store.holdGC
1307
+ let serialized = store->RescriptRelay.Store.getSource->RescriptRelay.RecordSource.toJSON
1308
+ // GC will resume automatically
1309
+ ```
1310
+ */
742
1311
  @send
743
1312
  external holdGC: t => unit = "holdGC"
744
1313
  }
@@ -786,12 +1355,45 @@ module RelayFieldLogger: {
786
1355
  type t = arg => unit
787
1356
  }
788
1357
 
789
- /**Module representing the environment, which you'll need to use and pass to various functions. Takes a few configuration options like store and network layer.*/
1358
+ /**
1359
+ The Relay Environment - the central hub for Relay operations.
1360
+
1361
+ The Environment coordinates between the network layer, store, and other Relay
1362
+ components. It manages data fetching, caching, and normalization. You typically
1363
+ create one Environment per application and pass it to Relay components.
1364
+ */
790
1365
  module Environment: {
791
- /**The type representing an instantiated `Environment`.*/
1366
+ /**The type representing a Relay environment instance.*/
792
1367
  type t
793
1368
 
794
- /**Create a new `Environment`.*/
1369
+ /**
1370
+ Creates a new Relay Environment.
1371
+
1372
+ The Environment requires a network layer and store at minimum. Additional
1373
+ configuration options allow you to customize caching, error handling,
1374
+ and data normalization behavior.
1375
+
1376
+ ## Parameters
1377
+ - `network`: Network layer for making GraphQL requests
1378
+ - `store`: Store for caching normalized data
1379
+ - `getDataID`: Optional custom function for generating record IDs
1380
+ - `treatMissingFieldsAsNull`: Whether missing fields should be treated as null
1381
+ - `missingFieldHandlers`: Array of handlers for filling in missing data
1382
+ - `relayFieldLogger`: Optional logger for field-level events
1383
+ - `isServer`: Whether this environment is running on the server
1384
+
1385
+ ## Examples
1386
+
1387
+ ```rescript
1388
+ let environment = RescriptRelay.Environment.make(
1389
+ ~network=myNetworkLayer,
1390
+ ~store=RescriptRelay.Store.make(
1391
+ ~source=RescriptRelay.RecordSource.make()
1392
+ ),
1393
+ ~treatMissingFieldsAsNull=false,
1394
+ )
1395
+ ```
1396
+ */
795
1397
  let make: (
796
1398
  ~network: Network.t,
797
1399
  ~store: Store.t,
@@ -805,24 +1407,118 @@ module Environment: {
805
1407
  ~isServer: bool=?,
806
1408
  ) => t
807
1409
 
808
- /**Get the `Store` for this `Environment`.*/
1410
+ /**
1411
+ Gets the store instance from this environment.
1412
+
1413
+ Provides access to the underlying store for advanced store operations
1414
+ like publishing records or holding garbage collection.
1415
+
1416
+ ## Examples
1417
+
1418
+ ```rescript
1419
+ let store = environment->RescriptRelay.Environment.getStore
1420
+ store->RescriptRelay.Store.holdGC // Prevent garbage collection
1421
+ ```
1422
+ */
809
1423
  @send
810
1424
  external getStore: t => Store.t = "getStore"
811
1425
 
812
- /**Given an `operationDescriptor`, commits the corresponding payload.*/
1426
+ /**
1427
+ Commits a GraphQL response payload to the store.
1428
+
1429
+ Low-level function for manually committing operation results. Most users
1430
+ should use higher-level APIs like queries and mutations instead.
1431
+
1432
+ ## Parameters
1433
+ - `operationDescriptor`: The operation that produced this payload
1434
+ - `payload`: The GraphQL response data to commit
1435
+ */
813
1436
  @send
814
1437
  external commitPayload: (t, operationDescriptor, 'payload) => unit = "commitPayload"
815
1438
 
816
- /**Given an `operationDescriptor`, retains the corresponding operation so any data referenced by it isn't garbage collected.
817
- You should use the generated `Query.retain` function on your queries instead of using this directly.*/
1439
+ /**
1440
+ Retains an operation to prevent garbage collection.
1441
+
1442
+ Keeps the data for an operation in the store by preventing Relay's garbage
1443
+ collector from cleaning it up. Returns a disposable that releases the retain
1444
+ when disposed.
1445
+
1446
+ Note: Use the generated `Query.retain` functions instead of calling this directly.
1447
+
1448
+ ## Parameters
1449
+ - `operationDescriptor`: The operation to retain
1450
+
1451
+ ## Returns
1452
+ Disposable that releases the retain when disposed
1453
+ */
818
1454
  @send
819
1455
  external retain: (t, operationDescriptor) => Disposable.t = "retain"
820
1456
 
821
- /**Find all connection IDs for a specific connection and on a specific object. Useful together with `@deleteEdge` and similar where you want to remove something from all connection configurations. */
1457
+ /**
1458
+ Finds all connection IDs for a specific connection key on a parent record.
1459
+
1460
+ Useful for operations that need to affect all instances of a connection,
1461
+ such as when using `@deleteEdge` or bulk connection updates.
1462
+
1463
+ ## Parameters
1464
+ - `connectionKey`: The connection key to search for
1465
+ - `parentId`: The parent record containing the connections
1466
+
1467
+ ## Returns
1468
+ Array of connection data IDs
1469
+
1470
+ ## Examples
1471
+
1472
+ ```rescript
1473
+ // Find all friend list connections for a user
1474
+ let connectionIds = environment->RescriptRelay.Environment.findAllConnectionIds(
1475
+ ~connectionKey=UserFriends_user_graphql.connectionKey,
1476
+ ~parentId=userId
1477
+ )
1478
+ ```
1479
+ */
822
1480
  let findAllConnectionIds: (t, ~connectionKey: string, ~parentId: dataId) => array<dataId>
823
1481
 
824
- /**Invalidates all connection configurations of `connectionKey` on `parentId`.*/
825
- let invalidateAllOfConnection: (t, ~connectionKey: string, ~parentId: dataId) => unit
1482
+ /**
1483
+ Invalidates all connection configurations of `connectionKey` on `parentId`.
1484
+
1485
+ This function invalidates all cached data for connections with the specified key on the given parent record.
1486
+ When connections are invalidated, any queries that depend on this connection data will be considered stale
1487
+ and will need to be refetched the next time they are accessed.
1488
+
1489
+ ## Parameters
1490
+ - `environment`: The Relay environment
1491
+ - `connectionKey`: The connection key used in the `@connection(key: "...")` directive
1492
+ - `parentId`: The data ID of the parent record that holds the connection
1493
+ - `excludedIds`: Optional array of connection data IDs to exclude from invalidation
1494
+
1495
+ ## Examples
1496
+
1497
+ ### Basic Usage
1498
+ ```rescript
1499
+ // Invalidate all connections for a user's friends
1500
+ environment->RescriptRelay.Environment.invalidateAllOfConnection(
1501
+ ~connectionKey=UserProfile_friends_graphql.connectionKey,
1502
+ ~parentId=user.__id,
1503
+ )
1504
+ ```
1505
+
1506
+ ### With Excluded IDs
1507
+ ```rescript
1508
+ environment->RescriptRelay.Environment.invalidateAllOfConnection(
1509
+ ~connectionKey=UserProfile_friends_graphql.connectionKey,
1510
+ ~parentId=user.__id,
1511
+ // Invalidate all of this connection except for the currently rendered one.
1512
+ ~excludedIds=[currentConnection.__id],
1513
+ )
1514
+ ```
1515
+ */
1516
+ let invalidateAllOfConnection: (
1517
+ t,
1518
+ ~connectionKey: string,
1519
+ ~parentId: dataId,
1520
+ ~excludedIds: array<dataId>=?,
1521
+ ) => unit
826
1522
  }
827
1523
 
828
1524
  /**fetchPolicy controls how you want Relay to resolve your data.*/
@@ -883,14 +1579,72 @@ let useEnvironmentFromContext: unit => Environment.t
883
1579
 
884
1580
  /**An exception detailing that a mutation failed.*/ exception Mutation_failed(array<mutationError>)
885
1581
 
886
- /**A way of committing a local update to the store.*/
1582
+ /**
1583
+ Commits a local update to the Relay store.
1584
+
1585
+ Performs imperative updates to the store without triggering network requests.
1586
+ Use this for client-side only changes like toggling UI state or updating
1587
+ local fields that don't need server synchronization.
1588
+
1589
+ ## Parameters
1590
+ - `environment`: The Relay environment
1591
+ - `updater`: Function that receives the store and performs updates
1592
+
1593
+ ## Examples
1594
+
1595
+ ```rescript
1596
+ // Toggle a local UI state
1597
+ RescriptRelay.commitLocalUpdate(
1598
+ ~environment,
1599
+ ~updater=store => {
1600
+ let user = store->RescriptRelay.RecordSourceSelectorProxy.get(~dataId=userId)
1601
+ switch user {
1602
+ | Some(userRecord) =>
1603
+ let _ = userRecord->RescriptRelay.RecordProxy.setValueBool(
1604
+ ~value=!isExpanded,
1605
+ ~name="isExpanded"
1606
+ )
1607
+ | None => ()
1608
+ }
1609
+ }
1610
+ )
1611
+ ```
1612
+ */
887
1613
  @module("relay-runtime")
888
1614
  external commitLocalUpdate: (
889
1615
  ~environment: Environment.t,
890
1616
  ~updater: RecordSourceSelectorProxy.t => unit,
891
1617
  ) => unit = "commitLocalUpdate"
892
1618
 
893
- /**Allows you to subscribe to when a record, connection, or even the store itself is invalidated, and then react to that.*/
1619
+ /**
1620
+ Subscribes to invalidation events for specific records.
1621
+
1622
+ Executes a callback whenever any of the specified records are invalidated.
1623
+ Useful for triggering refetches or UI updates when cached data becomes stale.
1624
+
1625
+ ## Parameters
1626
+ - Array of `dataId`s to watch for invalidation
1627
+ - Callback function executed when any watched record is invalidated
1628
+
1629
+ ## Examples
1630
+
1631
+ ```rescript
1632
+ // Watch for user invalidation and refetch
1633
+ let disposable = RescriptRelay.useSubscribeToInvalidationState(
1634
+ [user.__id],
1635
+ () => {
1636
+ // Refetch user data when invalidated
1637
+ UserQuery.fetchPromised(~environment, ~variables={id: user.id})
1638
+ ->Promise.done
1639
+ }
1640
+ )
1641
+
1642
+ // Clean up subscription
1643
+ React.useEffect1(() => {
1644
+ Some(() => disposable->RescriptRelay.Disposable.dispose)
1645
+ }, [disposable])
1646
+ ```
1647
+ */
894
1648
  @module("react-relay")
895
1649
  external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
896
1650
  "useSubscribeToInvalidationState"
package/src/utils.js CHANGED
@@ -79,6 +79,12 @@ function traverse(
79
79
  continue;
80
80
  }
81
81
 
82
+ if (currentObj[key] && currentObj[key].BS_PRIVATE_NESTED_SOME_NONE >= 0) {
83
+ newObj = getNewObj(newObj, currentObj);
84
+ newObj[key] = currentObj[key];
85
+ continue;
86
+ }
87
+
82
88
  var shouldConvertRootObj =
83
89
  typeof instructions["r"] === "string" &&
84
90
  fullInstructionMap[instructions["r"]];
package/src/utils.mjs CHANGED
@@ -79,6 +79,12 @@ function traverse(
79
79
  continue;
80
80
  }
81
81
 
82
+ if (currentObj[key] && currentObj[key].BS_PRIVATE_NESTED_SOME_NONE >= 0) {
83
+ newObj = getNewObj(newObj, currentObj);
84
+ newObj[key] = currentObj[key];
85
+ continue;
86
+ }
87
+
82
88
  var shouldConvertRootObj =
83
89
  typeof instructions["r"] === "string" &&
84
90
  fullInstructionMap[instructions["r"]];