rescript-relay 3.1.0 → 3.3.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 +17 -0
- package/package.json +1 -1
- package/ppx-linux +0 -0
- package/ppx-macos-arm64 +0 -0
- package/ppx-macos-latest +0 -0
- package/ppx-windows-latest +0 -0
- package/relay-compiler-linux-musl/relay +0 -0
- package/relay-compiler-linux-x64/relay +0 -0
- package/relay-compiler-macos-arm64/relay +0 -0
- package/relay-compiler-macos-x64/relay +0 -0
- package/relay-compiler-win-x64/relay.exe +0 -0
- package/src/RescriptRelay.bs.js +35 -4
- package/src/RescriptRelay.res +32 -6
- package/src/RescriptRelay.resi +830 -58
- package/src/RescriptRelay_Fragment.bs.js +6 -12
- package/src/RescriptRelay_Fragment.res +48 -31
- package/src/RescriptRelay_Fragment.resi +19 -14
- package/src/utils.js +6 -0
- package/src/utils.mjs +6 -0
package/src/RescriptRelay.resi
CHANGED
|
@@ -41,6 +41,24 @@ type dataId
|
|
|
41
41
|
|
|
42
42
|
type dataIdObject = {id: dataId}
|
|
43
43
|
|
|
44
|
+
/** A module for results originating from the @catch directive. */
|
|
45
|
+
module CatchResult: {
|
|
46
|
+
/** The shape of an error caught via @catch. */
|
|
47
|
+
type catchError = Js.Json.t
|
|
48
|
+
|
|
49
|
+
/** The result type for @catch. */
|
|
50
|
+
@tag("ok")
|
|
51
|
+
type t<'value> =
|
|
52
|
+
| @as(true) Ok({value: 'value})
|
|
53
|
+
| @as(false) Error({errors: array<catchError>})
|
|
54
|
+
|
|
55
|
+
/** Convert a @catch result to option. */
|
|
56
|
+
let toOption: t<'value> => option<'value>
|
|
57
|
+
|
|
58
|
+
/** Convert a @catch result to result. */
|
|
59
|
+
let toResult: t<'value> => result<'value, array<catchError>>
|
|
60
|
+
}
|
|
61
|
+
|
|
44
62
|
module SuspenseSentinel: {
|
|
45
63
|
type t
|
|
46
64
|
|
|
@@ -76,12 +94,56 @@ external makeUploadables: Js.Dict.t<'file> => uploadables = "%identity"
|
|
|
76
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.*/
|
|
77
95
|
external unwrapUploadables: uploadables => Js.Dict.t<'file> = "%identity"
|
|
78
96
|
|
|
79
|
-
/**
|
|
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
|
+
*/
|
|
80
118
|
@module("relay-runtime")
|
|
81
119
|
external generateClientID: (~dataId: dataId, ~storageKey: string, ~index: int=?) => dataId =
|
|
82
120
|
"generateClientID"
|
|
83
121
|
|
|
84
|
-
/**
|
|
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
|
+
*/
|
|
85
147
|
@module("relay-runtime")
|
|
86
148
|
external generateUniqueClientID: unit => dataId = "generateUniqueClientID"
|
|
87
149
|
|
|
@@ -153,15 +215,70 @@ module RecordProxy: {
|
|
|
153
215
|
/**Read the following section on working with the Relay store: https://relay.dev/docs/en/relay-store*/
|
|
154
216
|
type t
|
|
155
217
|
|
|
156
|
-
/**
|
|
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
|
+
*/
|
|
157
236
|
@send
|
|
158
237
|
external copyFieldsFrom: (t, ~sourceRecord: t) => unit = "copyFieldsFrom"
|
|
159
238
|
|
|
160
|
-
/**
|
|
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
|
+
*/
|
|
161
254
|
@send
|
|
162
255
|
external getDataId: t => dataId = "getDataID"
|
|
163
256
|
|
|
164
|
-
/**
|
|
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
|
+
*/
|
|
165
282
|
@send
|
|
166
283
|
@return(nullable)
|
|
167
284
|
external getLinkedRecord: (t, ~name: string, ~arguments: arguments=?) => option<t> =
|
|
@@ -240,12 +357,56 @@ module RecordProxy: {
|
|
|
240
357
|
~arguments: arguments=?,
|
|
241
358
|
) => option<array<option<bool>>> = "getValue"
|
|
242
359
|
|
|
243
|
-
/**
|
|
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
|
+
*/
|
|
244
383
|
@send
|
|
245
384
|
external setLinkedRecord: (t, ~record: t, ~name: string, ~arguments: arguments=?) => t =
|
|
246
385
|
"setLinkedRecord"
|
|
247
386
|
|
|
248
|
-
/**
|
|
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
|
+
*/
|
|
249
410
|
@send
|
|
250
411
|
external setLinkedRecords: (
|
|
251
412
|
t,
|
|
@@ -371,15 +532,78 @@ module RecordSourceSelectorProxy: {
|
|
|
371
532
|
@send
|
|
372
533
|
external batchLiveStateUpdates: (t, unit => unit) => unit = "batchLiveStateUpdates"
|
|
373
534
|
|
|
374
|
-
/**
|
|
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
|
+
*/
|
|
375
559
|
@send
|
|
376
560
|
external create: (t, ~dataId: dataId, ~typeName: string) => RecordProxy.t = "create"
|
|
377
561
|
|
|
378
|
-
/**
|
|
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
|
+
*/
|
|
379
580
|
@send
|
|
380
581
|
external delete: (t, ~dataId: dataId) => unit = "delete"
|
|
381
582
|
|
|
382
|
-
/**
|
|
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
|
+
*/
|
|
383
607
|
@send
|
|
384
608
|
@return(nullable)
|
|
385
609
|
external get: (t, ~dataId: dataId) => option<RecordProxy.t> = "get"
|
|
@@ -505,9 +729,37 @@ module MissingFieldHandler: {
|
|
|
505
729
|
) => t
|
|
506
730
|
}
|
|
507
731
|
|
|
508
|
-
/**
|
|
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
|
+
*/
|
|
509
741
|
module ConnectionHandler: {
|
|
510
|
-
/**
|
|
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
|
+
*/
|
|
511
763
|
@module("relay-runtime")
|
|
512
764
|
@scope("ConnectionHandler")
|
|
513
765
|
@return(nullable)
|
|
@@ -517,7 +769,32 @@ module ConnectionHandler: {
|
|
|
517
769
|
~filters: arguments=?,
|
|
518
770
|
) => option<RecordProxy.t> = "getConnection"
|
|
519
771
|
|
|
520
|
-
/**
|
|
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
|
+
*/
|
|
521
798
|
@module("relay-runtime")
|
|
522
799
|
@scope("ConnectionHandler")
|
|
523
800
|
external createEdge: (
|
|
@@ -527,7 +804,36 @@ module ConnectionHandler: {
|
|
|
527
804
|
~edgeType: string,
|
|
528
805
|
) => RecordProxy.t = "createEdge"
|
|
529
806
|
|
|
530
|
-
/**
|
|
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
|
+
*/
|
|
531
837
|
@module("relay-runtime")
|
|
532
838
|
@scope("ConnectionHandler")
|
|
533
839
|
external insertEdgeBefore: (
|
|
@@ -536,7 +842,29 @@ module ConnectionHandler: {
|
|
|
536
842
|
~cursor: string=?,
|
|
537
843
|
) => unit = "insertEdgeBefore"
|
|
538
844
|
|
|
539
|
-
/**
|
|
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
|
+
*/
|
|
540
868
|
@module("relay-runtime")
|
|
541
869
|
@scope("ConnectionHandler")
|
|
542
870
|
external insertEdgeAfter: (
|
|
@@ -545,12 +873,59 @@ module ConnectionHandler: {
|
|
|
545
873
|
~cursor: string=?,
|
|
546
874
|
) => unit = "insertEdgeAfter"
|
|
547
875
|
|
|
548
|
-
/**
|
|
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
|
+
*/
|
|
549
898
|
@module("relay-runtime")
|
|
550
899
|
@scope("ConnectionHandler")
|
|
551
900
|
external deleteNode: (~connection: RecordProxy.t, ~nodeId: dataId) => unit = "deleteNode"
|
|
552
901
|
|
|
553
|
-
/**
|
|
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
|
+
*/
|
|
554
929
|
@module("relay-runtime")
|
|
555
930
|
@scope("ConnectionHandler")
|
|
556
931
|
external getConnectionID: (dataId, string, 'filters) => dataId = "getConnectionID"
|
|
@@ -612,28 +987,73 @@ module Observable: {
|
|
|
612
987
|
/**Ignore this subscription.*/ external ignoreSubscription: subscription => unit = "%ignore"
|
|
613
988
|
}
|
|
614
989
|
|
|
615
|
-
/**
|
|
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
|
+
*/
|
|
616
997
|
module Network: {
|
|
617
998
|
type codesplitsMetadata = (string, unit => unit)
|
|
618
999
|
|
|
619
1000
|
type operationMetadata = {codesplits?: array<codesplitsMetadata>}
|
|
620
1001
|
|
|
621
|
-
/**The type representing an instantiated
|
|
1002
|
+
/**The type representing an instantiated network layer.*/
|
|
622
1003
|
type t
|
|
623
1004
|
|
|
624
|
-
/**
|
|
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
|
+
*/
|
|
625
1019
|
type operation = {
|
|
626
|
-
|
|
627
|
-
|
|
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. */
|
|
628
1025
|
name: string,
|
|
1026
|
+
/** The operation kind. */
|
|
629
1027
|
operationKind: string,
|
|
1028
|
+
/** Optional operation metadata. */
|
|
630
1029
|
metadata: Js.Nullable.t<operationMetadata>,
|
|
631
1030
|
}
|
|
632
1031
|
|
|
633
|
-
/**
|
|
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
|
+
*/
|
|
634
1043
|
type subscribeFn = (operation, Js.Json.t, cacheConfig) => Observable.t<Js.Json.t>
|
|
635
1044
|
|
|
636
|
-
/**
|
|
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
|
+
*/
|
|
637
1057
|
type fetchFunctionPromise = (
|
|
638
1058
|
operation,
|
|
639
1059
|
Js.Json.t,
|
|
@@ -641,7 +1061,18 @@ module Network: {
|
|
|
641
1061
|
Js.Nullable.t<uploadables>,
|
|
642
1062
|
) => Js.Promise.t<Js.Json.t>
|
|
643
1063
|
|
|
644
|
-
/**
|
|
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
|
+
*/
|
|
645
1076
|
type fetchFunctionObservable = (
|
|
646
1077
|
operation,
|
|
647
1078
|
Js.Json.t,
|
|
@@ -649,7 +1080,16 @@ module Network: {
|
|
|
649
1080
|
Js.Nullable.t<uploadables>,
|
|
650
1081
|
) => Observable.t<Js.Json.t>
|
|
651
1082
|
|
|
652
|
-
/**
|
|
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
|
+
*/
|
|
653
1093
|
@module("relay-runtime")
|
|
654
1094
|
@scope("Network")
|
|
655
1095
|
external makePromiseBased: (
|
|
@@ -657,7 +1097,16 @@ module Network: {
|
|
|
657
1097
|
~subscriptionFunction: subscribeFn=?,
|
|
658
1098
|
) => t = "create"
|
|
659
1099
|
|
|
660
|
-
/**
|
|
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
|
+
*/
|
|
661
1110
|
@module("relay-runtime")
|
|
662
1111
|
@scope("Network")
|
|
663
1112
|
external makeObservableBased: (
|
|
@@ -665,62 +1114,200 @@ module Network: {
|
|
|
665
1114
|
~subscriptionFunction: subscribeFn=?,
|
|
666
1115
|
) => t = "create"
|
|
667
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
|
+
*/
|
|
668
1123
|
let preloadResources: (~operation: operation, ~variables: Js.Json.t, ~response: Js.Json.t) => unit
|
|
669
1124
|
}
|
|
670
1125
|
|
|
671
|
-
/**
|
|
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
|
+
*/
|
|
672
1133
|
module RecordSource: {
|
|
673
|
-
/**The type representing
|
|
1134
|
+
/**The type representing a RecordSource instance.*/
|
|
674
1135
|
type t
|
|
675
1136
|
|
|
676
|
-
/**
|
|
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
|
+
*/
|
|
677
1159
|
@module("relay-runtime")
|
|
678
1160
|
@new
|
|
679
1161
|
external make: (~records: recordSourceRecords=?) => t = "RecordSource"
|
|
680
1162
|
|
|
681
|
-
/**
|
|
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
|
+
*/
|
|
682
1183
|
@send
|
|
683
1184
|
external toJSON: t => recordSourceRecords = "toJSON"
|
|
684
1185
|
}
|
|
685
1186
|
|
|
686
|
-
/**
|
|
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
|
+
*/
|
|
687
1194
|
module Store: {
|
|
688
|
-
/**The type representing
|
|
1195
|
+
/**The type representing a Relay store instance.*/
|
|
689
1196
|
type t
|
|
690
1197
|
|
|
691
|
-
/**
|
|
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
|
+
*/
|
|
692
1219
|
let make: (
|
|
693
1220
|
~source: RecordSource.t,
|
|
694
|
-
~gcReleaseBufferSize:
|
|
695
|
-
int=?,
|
|
1221
|
+
~gcReleaseBufferSize: int=?,
|
|
696
1222
|
~queryCacheExpirationTime: int=?,
|
|
697
|
-
) =>
|
|
698
|
-
|
|
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.
|
|
1232
|
+
|
|
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
|
|
699
1239
|
|
|
700
|
-
|
|
1240
|
+
```rescript
|
|
1241
|
+
let liveStore = RescriptRelay.Store.makeLiveStore(
|
|
1242
|
+
~source=RescriptRelay.RecordSource.make(),
|
|
1243
|
+
~gcReleaseBufferSize=15,
|
|
1244
|
+
)
|
|
1245
|
+
```
|
|
1246
|
+
*/
|
|
701
1247
|
let makeLiveStore: (
|
|
702
1248
|
~source: RecordSource.t,
|
|
703
|
-
~gcReleaseBufferSize:
|
|
704
|
-
int=?,
|
|
1249
|
+
~gcReleaseBufferSize: int=?,
|
|
705
1250
|
~queryCacheExpirationTime: int=?,
|
|
706
|
-
) =>
|
|
707
|
-
t
|
|
1251
|
+
) => t
|
|
708
1252
|
|
|
1253
|
+
/**Internal CommonJS version of makeLiveStore. Use `makeLiveStore` instead.*/
|
|
709
1254
|
let _makeLiveStoreCjs: (
|
|
710
1255
|
~source: RecordSource.t,
|
|
711
1256
|
~gcReleaseBufferSize: int=?,
|
|
712
1257
|
~queryCacheExpirationTime: int=?,
|
|
713
1258
|
) => t
|
|
714
1259
|
|
|
715
|
-
/**
|
|
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
|
+
*/
|
|
716
1273
|
@send
|
|
717
1274
|
external getSource: t => RecordSource.t = "getSource"
|
|
718
1275
|
|
|
719
|
-
/**
|
|
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
|
+
*/
|
|
720
1293
|
@send
|
|
721
1294
|
external publish: (t, RecordSource.t) => unit = "publish"
|
|
722
1295
|
|
|
723
|
-
/**
|
|
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
|
+
*/
|
|
724
1311
|
@send
|
|
725
1312
|
external holdGC: t => unit = "holdGC"
|
|
726
1313
|
}
|
|
@@ -768,12 +1355,45 @@ module RelayFieldLogger: {
|
|
|
768
1355
|
type t = arg => unit
|
|
769
1356
|
}
|
|
770
1357
|
|
|
771
|
-
/**
|
|
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
|
+
*/
|
|
772
1365
|
module Environment: {
|
|
773
|
-
/**The type representing
|
|
1366
|
+
/**The type representing a Relay environment instance.*/
|
|
774
1367
|
type t
|
|
775
1368
|
|
|
776
|
-
/**
|
|
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
|
+
*/
|
|
777
1397
|
let make: (
|
|
778
1398
|
~network: Network.t,
|
|
779
1399
|
~store: Store.t,
|
|
@@ -787,24 +1407,118 @@ module Environment: {
|
|
|
787
1407
|
~isServer: bool=?,
|
|
788
1408
|
) => t
|
|
789
1409
|
|
|
790
|
-
/**
|
|
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
|
+
*/
|
|
791
1423
|
@send
|
|
792
1424
|
external getStore: t => Store.t = "getStore"
|
|
793
1425
|
|
|
794
|
-
/**
|
|
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
|
+
*/
|
|
795
1436
|
@send
|
|
796
1437
|
external commitPayload: (t, operationDescriptor, 'payload) => unit = "commitPayload"
|
|
797
1438
|
|
|
798
|
-
/**
|
|
799
|
-
|
|
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
|
+
*/
|
|
800
1454
|
@send
|
|
801
1455
|
external retain: (t, operationDescriptor) => Disposable.t = "retain"
|
|
802
1456
|
|
|
803
|
-
/**
|
|
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
|
+
*/
|
|
804
1480
|
let findAllConnectionIds: (t, ~connectionKey: string, ~parentId: dataId) => array<dataId>
|
|
805
1481
|
|
|
806
|
-
/**
|
|
807
|
-
|
|
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
|
|
808
1522
|
}
|
|
809
1523
|
|
|
810
1524
|
/**fetchPolicy controls how you want Relay to resolve your data.*/
|
|
@@ -865,14 +1579,72 @@ let useEnvironmentFromContext: unit => Environment.t
|
|
|
865
1579
|
|
|
866
1580
|
/**An exception detailing that a mutation failed.*/ exception Mutation_failed(array<mutationError>)
|
|
867
1581
|
|
|
868
|
-
/**
|
|
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
|
+
*/
|
|
869
1613
|
@module("relay-runtime")
|
|
870
1614
|
external commitLocalUpdate: (
|
|
871
1615
|
~environment: Environment.t,
|
|
872
1616
|
~updater: RecordSourceSelectorProxy.t => unit,
|
|
873
1617
|
) => unit = "commitLocalUpdate"
|
|
874
1618
|
|
|
875
|
-
/**
|
|
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
|
+
*/
|
|
876
1648
|
@module("react-relay")
|
|
877
1649
|
external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
|
|
878
1650
|
"useSubscribeToInvalidationState"
|