rescript-relay 0.0.0-cli-61b2cdf6 → 0.0.0-next-af0f6500

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.
@@ -11,7 +11,7 @@ type subscriptionNode<'node>
11
11
  type fragmentRefs<'fragments>
12
12
 
13
13
  type dataId
14
- type recordSourceRecords
14
+ type recordSourceRecords = Js.Json.t
15
15
  type uploadables
16
16
 
17
17
  external dataIdToString: dataId => string = "%identity"
@@ -31,14 +31,40 @@ external generateUniqueClientID: unit => dataId = "generateUniqueClientID"
31
31
  external isClientID: dataId => bool = "isClientID"
32
32
 
33
33
  type featureFlags = {
34
+ @as("DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES")
35
+ mutable delayCleanupOfPendingPreloadQueries: bool,
36
+ @as("ENABLE_CLIENT_EDGES")
37
+ mutable enableClientEdges: bool,
34
38
  @as("ENABLE_VARIABLE_CONNECTION_KEY")
35
39
  mutable enableVariableConnectionKey: bool,
36
40
  @as("ENABLE_PARTIAL_RENDERING_DEFAULT")
37
41
  mutable enablePartialRenderingDefault: bool,
38
- @as("ENABLE_RELAY_CONTAINERS_SUSPENSE")
39
- mutable enableRelayContainersSuspense: bool,
40
- @as("ENABLE_PRECISE_TYPE_REFINEMENT")
41
- mutable enablePrecisTypeRefinement: bool,
42
+ @as("ENABLE_REACT_FLIGHT_COMPONENT_FIELD")
43
+ mutable enableReactFlightComponentField: bool,
44
+ @as("ENABLE_RELAY_RESOLVERS")
45
+ mutable enableRelayResolvers: bool,
46
+ @as("ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION")
47
+ mutable enableGetFragmentIdentifierOptimization: bool,
48
+ @as("ENABLE_FRIENDLY_QUERY_NAME_GQL_URL")
49
+ mutable enableFriendlyQueryNameGqlUrl: bool,
50
+ @as("ENABLE_LOAD_QUERY_REQUEST_DEDUPING")
51
+ mutable enableLoadQueryRequestDeduping: bool,
52
+ @as("ENABLE_DO_NOT_WRAP_LIVE_QUERY")
53
+ mutable enableDoNotWrapLiveQuery: bool,
54
+ @as("ENABLE_NOTIFY_SUBSCRIPTION")
55
+ mutable enableNotifySubscription: bool,
56
+ @as("ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT")
57
+ mutable enableContainersSubscribeOnCommit: bool,
58
+ @as("ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT")
59
+ mutable enableQueryRendererOffscreenSupport: bool,
60
+ @as("MAX_DATA_ID_LENGTH")
61
+ mutable maxDataIdLength: option<int>,
62
+ @as("REFACTOR_SUSPENSE_RESOURCE")
63
+ mutable refactorSuspenseResource: bool,
64
+ @as("STRING_INTERN_LEVEL")
65
+ mutable stringInternLevel: int,
66
+ @as("USE_REACT_CACHE")
67
+ mutable useReactCache: bool,
42
68
  }
43
69
 
44
70
  @module("relay-runtime")
@@ -140,6 +166,10 @@ module RecordProxy = {
140
166
  external setLinkedRecord: (t, ~record: t, ~name: string, ~arguments: arguments=?, unit) => t =
141
167
  "setLinkedRecord"
142
168
 
169
+ // `setLinkedRecord` can't be used for "deleting" linked record fields.
170
+ // It throws an error if anything besides `record` is received:
171
+ // https://github.com/facebook/relay/blob/bd2e4173ef726804b2ed4e76d88a7bcc1753c496/packages/relay-runtime/mutations/RelayRecordProxy.js#L92
172
+ // However, `setValue` can be used for this purpose instead.
143
173
  @send
144
174
  external setLinkedRecordToUndefined: (
145
175
  t,
@@ -147,7 +177,7 @@ module RecordProxy = {
147
177
  ~name: string,
148
178
  ~arguments: arguments=?,
149
179
  unit,
150
- ) => t = "setLinkedRecord"
180
+ ) => t = "setValue"
151
181
 
152
182
  @send
153
183
  external setLinkedRecordToNull: (
@@ -156,7 +186,7 @@ module RecordProxy = {
156
186
  ~name: string,
157
187
  ~arguments: arguments=?,
158
188
  unit,
159
- ) => t = "setLinkedRecord"
189
+ ) => t = "setValue"
160
190
 
161
191
  @send
162
192
  external setLinkedRecords: (
@@ -167,6 +197,10 @@ module RecordProxy = {
167
197
  unit,
168
198
  ) => t = "setLinkedRecords"
169
199
 
200
+ // `setLinkedRecords` can't be used for "deleting" linked records.
201
+ // It throws an error if anything besides an array of `records` is received:
202
+ // https://github.com/facebook/relay/blob/bd2e4173ef726804b2ed4e76d88a7bcc1753c496/packages/relay-runtime/mutations/RelayRecordProxy.js#L140
203
+ // However, `setValue` can be used for this purpose instead.
170
204
  @send
171
205
  external setLinkedRecordsToUndefined: (
172
206
  t,
@@ -174,7 +208,7 @@ module RecordProxy = {
174
208
  ~name: string,
175
209
  ~arguments: arguments=?,
176
210
  unit,
177
- ) => t = "setLinkedRecords"
211
+ ) => t = "setValue"
178
212
 
179
213
  @send
180
214
  external setLinkedRecordsToNull: (
@@ -183,7 +217,7 @@ module RecordProxy = {
183
217
  ~name: string,
184
218
  ~arguments: arguments=?,
185
219
  unit,
186
- ) => t = "setLinkedRecords"
220
+ ) => t = "setValue"
187
221
 
188
222
  @send
189
223
  external setValueToUndefined: (
@@ -371,12 +405,16 @@ module MissingFieldHandler = {
371
405
  }
372
406
 
373
407
  // This handler below enables automatic resolution of all cached items through the Node interface
374
- let nodeInterfaceMissingFieldHandler = MissingFieldHandler.makeLinkedMissingFieldHandler(
375
- (field, record, args, _store) =>
376
- switch (Js.Nullable.toOption(record), field["name"], Js.Nullable.toOption(args["id"])) {
377
- | (Some(record), "node", argsId) when record["__typename"] == storeRootType => argsId
378
- | _ => None
379
- },
408
+ let nodeInterfaceMissingFieldHandler = MissingFieldHandler.makeLinkedMissingFieldHandler((
409
+ field,
410
+ record,
411
+ args,
412
+ _store,
413
+ ) =>
414
+ switch (Js.Nullable.toOption(record), field["name"], Js.Nullable.toOption(args["id"])) {
415
+ | (Some(record), "node", argsId) if record["__typename"] == storeRootType => argsId
416
+ | _ => None
417
+ }
380
418
  )
381
419
 
382
420
  module ConnectionHandler = {
@@ -443,9 +481,9 @@ module Observable = {
443
481
  }
444
482
 
445
483
  type sink<'response> = {
446
- next: 'response => unit,
447
- error: Js.Exn.t => unit,
448
- complete: unit => unit,
484
+ next: (. 'response) => unit,
485
+ error: (. Js.Exn.t) => unit,
486
+ complete: (. unit) => unit,
449
487
  closed: bool,
450
488
  }
451
489
 
@@ -453,11 +491,11 @@ module Observable = {
453
491
 
454
492
  @obj
455
493
  external makeObserver: (
456
- ~start: subscription => unit=?,
457
- ~next: 'response => unit=?,
458
- ~error: Js.Exn.t => unit=?,
459
- ~complete: unit => unit=?,
460
- ~unsubscribe: subscription => unit=?,
494
+ ~start: @uncurry subscription => unit=?,
495
+ ~next: @uncurry 'response => unit=?,
496
+ ~error: @uncurry Js.Exn.t => unit=?,
497
+ ~complete: @uncurry unit => unit=?,
498
+ ~unsubscribe: @uncurry subscription => unit=?,
461
499
  unit,
462
500
  ) => observer<'response> = ""
463
501
 
@@ -467,7 +505,7 @@ module Observable = {
467
505
  @send
468
506
  external subscribe: (t<'response>, observer<'response>) => subscription = "subscribe"
469
507
 
470
- @send external toPromise: t<'t> => Promise.t<'t> = "toPromise"
508
+ @send external toPromise: t<'t> => Js.Promise.t<'t> = "toPromise"
471
509
  }
472
510
 
473
511
  module Network = {
@@ -542,6 +580,20 @@ module Store = {
542
580
 
543
581
  @send external getSource: t => RecordSource.t = "getSource"
544
582
  @send external publish: (t, RecordSource.t) => unit = "publish"
583
+ @send external holdGC: t => unit = "holdGC"
584
+ }
585
+
586
+ module RequiredFieldLogger = {
587
+ type kind = [#"missing_field.log" | #"missing_field.throw"]
588
+
589
+ type arg = {"kind": kind, "owner": string, "fieldPath": string}
590
+
591
+ type js = arg => unit
592
+
593
+ type t = (~kind: kind, ~owner: string, ~fieldPath: string) => unit
594
+
595
+ let toJs: t => js = (f, arg) =>
596
+ f(~kind=arg["kind"], ~owner=arg["owner"], ~fieldPath=arg["fieldPath"])
545
597
  }
546
598
 
547
599
  module Environment = {
@@ -556,6 +608,10 @@ module Environment = {
556
608
  @optional
557
609
  treatMissingFieldsAsNull: bool,
558
610
  missingFieldHandlers: array<MissingFieldHandler.t>,
611
+ @optional
612
+ requiredFieldLogger: RequiredFieldLogger.js,
613
+ @optional
614
+ isServer: bool,
559
615
  }
560
616
 
561
617
  @module("relay-runtime") @new
@@ -567,6 +623,8 @@ module Environment = {
567
623
  ~getDataID=?,
568
624
  ~treatMissingFieldsAsNull=?,
569
625
  ~missingFieldHandlers=?,
626
+ ~requiredFieldLogger=?,
627
+ ~isServer=?,
570
628
  (),
571
629
  ) =>
572
630
  make(
@@ -579,6 +637,8 @@ module Environment = {
579
637
  | Some(handlers) => handlers->Belt.Array.concat([nodeInterfaceMissingFieldHandler])
580
638
  | None => [nodeInterfaceMissingFieldHandler]
581
639
  },
640
+ ~requiredFieldLogger=?requiredFieldLogger->Belt.Option.map(RequiredFieldLogger.toJs),
641
+ ~isServer?,
582
642
  (),
583
643
  ),
584
644
  )
@@ -596,15 +656,16 @@ module Context = {
596
656
 
597
657
  @module("react-relay")
598
658
  external context: React.Context.t<option<contextShape>> = "ReactRelayContext"
599
- let provider = React.Context.provider(context)
600
659
 
601
660
  module Provider = {
602
661
  @react.component
603
- let make = (~environment: Environment.t, ~children) =>
662
+ let make = (~environment: Environment.t, ~children) => {
663
+ let provider = React.Context.provider(context)
604
664
  React.createElement(
605
665
  provider,
606
666
  {"value": Some({"environment": environment}), "children": children},
607
667
  )
668
+ }
608
669
  }
609
670
  }
610
671
 
@@ -656,7 +717,7 @@ type loadQueryConfig = {
656
717
  networkCacheConfig: option<cacheConfig>,
657
718
  }
658
719
 
659
- @module("react-relay/hooks")
720
+ @module("react-relay")
660
721
  external loadQuery: (Environment.t, queryNode<'a>, 'variables, loadQueryConfig) => 'queryResponse =
661
722
  "loadQuery"
662
723
 
@@ -705,18 +766,16 @@ module MakeLoadQuery = (C: MakeLoadQueryConfig) => {
705
766
  }
706
767
 
707
768
  let queryRefToPromise = token => {
708
- let (promise, resolve) = Promise.pending()
709
-
710
- switch token->queryRefToObservable {
711
- | None => resolve(Error())
712
- | Some(o) =>
713
- let _: Observable.subscription = o->{
714
- open Observable
715
- subscribe(makeObserver(~complete=() => resolve(Ok()), ()))
769
+ Js.Promise.make((~resolve, ~reject as _) => {
770
+ switch token->queryRefToObservable {
771
+ | None => resolve(. Error())
772
+ | Some(o) =>
773
+ let _: Observable.subscription = o->{
774
+ open Observable
775
+ subscribe(makeObserver(~complete=() => resolve(. Ok()), ()))
776
+ }
716
777
  }
717
- }
718
-
719
- promise
778
+ })
720
779
  }
721
780
  }
722
781
 
@@ -730,6 +789,6 @@ external commitLocalUpdate: (
730
789
  ~updater: RecordSourceSelectorProxy.t => unit,
731
790
  ) => unit = "commitLocalUpdate"
732
791
 
733
- @module("react-relay/hooks")
792
+ @module("react-relay")
734
793
  external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
735
794
  "useSubscribeToInvalidationState"
@@ -3,14 +3,12 @@
3
3
  )
4
4
  type arguments
5
5
 
6
- @ocaml.doc(
7
- "Abstract type for uploadables.
6
+ @ocaml.doc("Abstract type for uploadables.
8
7
 
9
8
  ### Constructing an `uploadables`
10
9
  Use `makeUploadable`: `makeUploadable({ \"someFile\": theFileYouWantToUpload })` to construct an `uploadables`, and then pass it to your mutation via the `uploadables` prop.
11
10
 
12
- Please note that you'll need to handle _sending_ the uploadables to your server yourself in the network layer. [Here's an example](https://github.com/facebook/relay/issues/1844#issuecomment-316893590) in regular JS that you can adapt to ReScript as you need/want."
13
- )
11
+ Please note that you'll need to handle _sending_ the uploadables to your server yourself in the network layer. [Here's an example](https://github.com/facebook/relay/issues/1844#issuecomment-316893590) in regular JS that you can adapt to ReScript as you need/want.")
14
12
  type uploadables
15
13
 
16
14
  @ocaml.doc(
@@ -55,12 +53,10 @@ external dataIdToString: dataId => string = "%identity"
55
53
  @ocaml.doc("Turns a `string` into a `dataId`.")
56
54
  external makeDataId: string => dataId = "%identity"
57
55
 
58
- @ocaml.doc(
59
- "Construct an `arguments` object for use with certain Relay store APIs.
56
+ @ocaml.doc("Construct an `arguments` object for use with certain Relay store APIs.
60
57
 
61
58
  ### Usage
62
- Use it like this: `makeArguments({ \"someArgument\": someValue, \"anotherArgument\": anotherValue })`. Notice the \"\" surrounding the property names - these are important and tells ReScript that we want this to be a JS object."
63
- )
59
+ Use it like this: `makeArguments({ \"someArgument\": someValue, \"anotherArgument\": anotherValue })`. Notice the \"\" surrounding the property names - these are important and tells ReScript that we want this to be a JS object.")
64
60
  external makeArguments: {..} => arguments = "%identity"
65
61
 
66
62
  @ocaml.doc(
@@ -94,14 +90,40 @@ external isClientID: dataId => bool = "isClientID"
94
90
  "Relay feature flags. Mutate this record as soon as your application boots to enable/disable features."
95
91
  )
96
92
  type featureFlags = {
93
+ @as("DELAY_CLEANUP_OF_PENDING_PRELOAD_QUERIES")
94
+ mutable delayCleanupOfPendingPreloadQueries: bool,
95
+ @as("ENABLE_CLIENT_EDGES")
96
+ mutable enableClientEdges: bool,
97
97
  @as("ENABLE_VARIABLE_CONNECTION_KEY")
98
98
  mutable enableVariableConnectionKey: bool,
99
99
  @as("ENABLE_PARTIAL_RENDERING_DEFAULT")
100
100
  mutable enablePartialRenderingDefault: bool,
101
- @as("ENABLE_RELAY_CONTAINERS_SUSPENSE")
102
- mutable enableRelayContainersSuspense: bool,
103
- @as("ENABLE_PRECISE_TYPE_REFINEMENT")
104
- mutable enablePrecisTypeRefinement: bool,
101
+ @as("ENABLE_REACT_FLIGHT_COMPONENT_FIELD")
102
+ mutable enableReactFlightComponentField: bool,
103
+ @as("ENABLE_RELAY_RESOLVERS")
104
+ mutable enableRelayResolvers: bool,
105
+ @as("ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION")
106
+ mutable enableGetFragmentIdentifierOptimization: bool,
107
+ @as("ENABLE_FRIENDLY_QUERY_NAME_GQL_URL")
108
+ mutable enableFriendlyQueryNameGqlUrl: bool,
109
+ @as("ENABLE_LOAD_QUERY_REQUEST_DEDUPING")
110
+ mutable enableLoadQueryRequestDeduping: bool,
111
+ @as("ENABLE_DO_NOT_WRAP_LIVE_QUERY")
112
+ mutable enableDoNotWrapLiveQuery: bool,
113
+ @as("ENABLE_NOTIFY_SUBSCRIPTION")
114
+ mutable enableNotifySubscription: bool,
115
+ @as("ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT")
116
+ mutable enableContainersSubscribeOnCommit: bool,
117
+ @as("ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT")
118
+ mutable enableQueryRendererOffscreenSupport: bool,
119
+ @as("MAX_DATA_ID_LENGTH")
120
+ mutable maxDataIdLength: option<int>,
121
+ @as("REFACTOR_SUSPENSE_RESOURCE")
122
+ mutable refactorSuspenseResource: bool,
123
+ @as("STRING_INTERN_LEVEL")
124
+ mutable stringInternLevel: int,
125
+ @as("USE_REACT_CACHE")
126
+ mutable useReactCache: bool,
105
127
  }
106
128
 
107
129
  @ocaml.doc(
@@ -110,12 +132,10 @@ type featureFlags = {
110
132
  @module("relay-runtime")
111
133
  external relayFeatureFlags: featureFlags = "RelayFeatureFlags"
112
134
 
113
- @ocaml.doc(
114
- "An abstract type representing all records in the store serialized to JSON in a way that you can use to re-hydrate the store.
135
+ @ocaml.doc("Representing all records in the store serialized to JSON in a way that you can use to re-hydrate the store.
115
136
 
116
- See `RecordSource.toJSON` for how to produce it."
117
- )
118
- type recordSourceRecords
137
+ See `RecordSource.toJSON` for how to produce it.")
138
+ type recordSourceRecords = Js.Json.t
119
139
 
120
140
  @ocaml.doc(
121
141
  "The `dataId` for the Relay store's root. Useful when for example referencing the `parentID` of a connection that's on the store root."
@@ -325,7 +345,7 @@ module RecordProxy: {
325
345
  ~name: string,
326
346
  ~arguments: arguments=?,
327
347
  unit,
328
- ) => t = "setLinkedRecord"
348
+ ) => t = "setValue"
329
349
 
330
350
  @ocaml.doc("Sets this linked record to `null`.") @send
331
351
  external setLinkedRecordToNull: (
@@ -334,7 +354,7 @@ module RecordProxy: {
334
354
  ~name: string,
335
355
  ~arguments: arguments=?,
336
356
  unit,
337
- ) => t = "setLinkedRecord"
357
+ ) => t = "setValue"
338
358
 
339
359
  @ocaml.doc(
340
360
  "Sets the field holding these linked records to `undefined` (meaning Relay will treat it as missing data)."
@@ -346,7 +366,7 @@ module RecordProxy: {
346
366
  ~name: string,
347
367
  ~arguments: arguments=?,
348
368
  unit,
349
- ) => t = "setLinkedRecords"
369
+ ) => t = "setValue"
350
370
 
351
371
  @ocaml.doc("Sets the field holding these linked records to `null`.") @send
352
372
  external setLinkedRecordsToNull: (
@@ -355,15 +375,13 @@ module RecordProxy: {
355
375
  ~name: string,
356
376
  ~arguments: arguments=?,
357
377
  unit,
358
- ) => t = "setLinkedRecords"
378
+ ) => t = "setValue"
359
379
 
360
- @ocaml.doc(
361
- "Invalidates this record.
380
+ @ocaml.doc("Invalidates this record.
362
381
 
363
382
  Invalidating a record means that the _next_ time Relay evaluates this record, it'll be treated as missing.
364
383
 
365
- _Beware_ that this doesn't mean that queries using this record will refetch immediately. Rather, it'll happen the next time the query _renders_. Have a look at `useSubscribeToInvalidationState`, that'll allow you to subscribe to whenever records are invalidated, if you're looking for a way to refetch immediately as something invalidates."
366
- )
384
+ _Beware_ that this doesn't mean that queries using this record will refetch immediately. Rather, it'll happen the next time the query _renders_. Have a look at `useSubscribeToInvalidationState`, that'll allow you to subscribe to whenever records are invalidated, if you're looking for a way to refetch immediately as something invalidates.")
367
385
  @send
368
386
  external invalidateRecord: t => unit = "invalidateRecord"
369
387
  }
@@ -426,11 +444,9 @@ module ReadOnlyRecordSourceProxy: {
426
444
  external getRoot: t => RecordProxy.t = "getRoot"
427
445
  }
428
446
 
429
- @ocaml.doc(
430
- "A missing field handler, which is a way of teaching Relay more about the relations in your schema, so it can fulfill more things from the cache. Read more [in this section of the Relay docs](https://relay.dev/docs/guided-tour/reusing-cached-data/filling-in-missing-data/).
447
+ @ocaml.doc("A missing field handler, which is a way of teaching Relay more about the relations in your schema, so it can fulfill more things from the cache. Read more [in this section of the Relay docs](https://relay.dev/docs/guided-tour/reusing-cached-data/filling-in-missing-data/).
431
448
 
432
- Feed a list of missing field handlers into `Environment.make` if you want to use them."
433
- )
449
+ Feed a list of missing field handlers into `Environment.make` if you want to use them.")
434
450
  module MissingFieldHandler: {
435
451
  @@ocaml.warning("-30")
436
452
 
@@ -607,9 +623,9 @@ module Observable: {
607
623
 
608
624
  @ocaml.doc("This sink can be used to give the observable new data.")
609
625
  type sink<'response> = {
610
- next: 'response => unit,
611
- error: Js.Exn.t => unit,
612
- complete: unit => unit,
626
+ next: (. 'response) => unit,
627
+ error: (. Js.Exn.t) => unit,
628
+ complete: (. unit) => unit,
613
629
  closed: bool,
614
630
  }
615
631
 
@@ -624,10 +640,10 @@ module Observable: {
624
640
 
625
641
  @ocaml.doc("Create an observer.") @obj
626
642
  external makeObserver: (
627
- ~start: subscription => unit=?,
628
- ~next: 'response => unit=?,
629
- ~error: Js.Exn.t => unit=?,
630
- ~complete: unit => unit=?,
643
+ ~start: @uncurry subscription => unit=?,
644
+ ~next: @uncurry 'response => unit=?,
645
+ ~error: @uncurry Js.Exn.t => unit=?,
646
+ ~complete: @uncurry unit => unit=?,
631
647
  ~unsubscribe: subscription => unit=?,
632
648
  unit,
633
649
  ) => observer<'response> = ""
@@ -646,7 +662,7 @@ module Observable: {
646
662
  "Turns an `Observable` into a promise. _Beware_ that reading the response in the resulting promise is currently _not safe_ due to some internals of how ReScript Relay works. This will be resolved in the future."
647
663
  )
648
664
  @send
649
- external toPromise: t<'t> => Promise.t<'t> = "toPromise"
665
+ external toPromise: t<'t> => Js.Promise.t<'t> = "toPromise"
650
666
  }
651
667
 
652
668
  @ocaml.doc("Represents the network layer.")
@@ -737,7 +753,7 @@ module Store: {
737
753
  ~source: RecordSource.t,
738
754
  ~gcReleaseBufferSize: /* `gcReleaseBufferSize` controls how many queries are allowed to be cached by default. Increase this to increase the size of the cache. */
739
755
  int=?,
740
- ~queryCacheExpirationTime: int /* `queryCacheExpirationTime` sets a TTL (time to live) for all queries. If that time passes, the data is considered stale and is evicted from the store. Default is no TTL. */=?,
756
+ ~queryCacheExpirationTime: int=? /* `queryCacheExpirationTime` sets a TTL (time to live) for all queries. If that time passes, the data is considered stale and is evicted from the store. Default is no TTL. */,
741
757
  unit,
742
758
  ) => t
743
759
 
@@ -749,6 +765,12 @@ module Store: {
749
765
  )
750
766
  @send
751
767
  external publish: (t, RecordSource.t) => unit = "publish"
768
+
769
+ @ocaml.doc(
770
+ "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)"
771
+ )
772
+ @send
773
+ external holdGC: t => unit = "holdGC"
752
774
  }
753
775
 
754
776
  @ocaml.doc("Internal, do not use.")
@@ -764,6 +786,18 @@ module Disposable: {
764
786
  @ocaml.doc("Dispose the `Disposable`.") @send external dispose: t => unit = "dispose"
765
787
  }
766
788
 
789
+ @ocaml.doc(
790
+ "A required field logger, which gets called when a field annotated with the @required directive was missing from the response"
791
+ )
792
+ module RequiredFieldLogger: {
793
+ type kind = [#"missing_field.log" | #"missing_field.throw"]
794
+
795
+ @ocaml.doc(
796
+ "A required field logger, which gets called when a field annotated with the @required directive was missing from the response"
797
+ )
798
+ type t = (~kind: kind, ~owner: string, ~fieldPath: string) => unit
799
+ }
800
+
767
801
  @ocaml.doc(
768
802
  "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."
769
803
  )
@@ -781,6 +815,8 @@ module Environment: {
781
815
  ) => string=?,
782
816
  ~treatMissingFieldsAsNull: bool=?,
783
817
  ~missingFieldHandlers: array<MissingFieldHandler.t>=?,
818
+ ~requiredFieldLogger: RequiredFieldLogger.t=?,
819
+ ~isServer: bool=?,
784
820
  unit,
785
821
  ) => t
786
822
 
@@ -790,10 +826,8 @@ module Environment: {
790
826
  @ocaml.doc("Given an `operationDescriptor`, commits the corresponding payload.") @send
791
827
  external commitPayload: (t, operationDescriptor, 'payload) => unit = "commitPayload"
792
828
 
793
- @ocaml.doc(
794
- "Given an `operationDescriptor`, retains the corresponding operation so any data referenced by it isn't garbage collected.
795
- You should use the generated `Query.retain` function on your queries instead of using this directly."
796
- )
829
+ @ocaml.doc("Given an `operationDescriptor`, retains the corresponding operation so any data referenced by it isn't garbage collected.
830
+ You should use the generated `Query.retain` function on your queries instead of using this directly.")
797
831
  @send
798
832
  external retain: (t, operationDescriptor) => Disposable.t = "retain"
799
833
  }
@@ -864,7 +898,7 @@ external commitLocalUpdate: (
864
898
  @ocaml.doc(
865
899
  "Allows you to subscribe to when a record, connection, or even the store itself is invalidated, and then react to that."
866
900
  )
867
- @module("react-relay/hooks")
901
+ @module("react-relay")
868
902
  external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
869
903
  "useSubscribeToInvalidationState"
870
904
 
@@ -897,5 +931,5 @@ module MakeLoadQuery: (C: MakeLoadQueryConfig) =>
897
931
  ) => C.loadedQueryRef
898
932
 
899
933
  let queryRefToObservable: C.loadedQueryRef => option<Observable.t<C.response>>
900
- let queryRefToPromise: C.loadedQueryRef => Promise.t<Belt.Result.t<unit, unit>>
934
+ let queryRefToPromise: C.loadedQueryRef => Js.Promise.t<Belt.Result.t<unit, unit>>
901
935
  }
@@ -3,23 +3,56 @@
3
3
 
4
4
  var Curry = require("rescript/lib/js/curry.js");
5
5
  var React = require("react");
6
+ var Js_dict = require("rescript/lib/js/js_dict.js");
7
+ var Caml_obj = require("rescript/lib/js/caml_obj.js");
8
+ var Belt_Array = require("rescript/lib/js/belt_Array.js");
9
+ var Belt_Option = require("rescript/lib/js/belt_Option.js");
6
10
  var Caml_option = require("rescript/lib/js/caml_option.js");
7
11
 
8
- var internal_cleanObjectFromUndefinedRaw = (function (obj) {
9
- if (!obj) {
10
- return obj;
11
- }
12
-
13
- var newObj = {};
12
+ function internal_keepMapFieldsRaw(record, f) {
13
+ return Belt_Option.map(record, (function (obj) {
14
+ return Js_dict.fromArray(Belt_Array.keepMap(Js_dict.entries(obj), f));
15
+ }));
16
+ }
14
17
 
15
- Object.keys(obj).forEach(function(key) {
16
- if (typeof obj[key] !== 'undefined') {
17
- newObj[key] = obj[key];
18
- }
19
- });
18
+ function internal_cleanObjectFromUndefinedRaw(record) {
19
+ var v = internal_keepMapFieldsRaw(record, (function (param) {
20
+ var value = param[1];
21
+ if (value !== undefined) {
22
+ return [
23
+ param[0],
24
+ Caml_option.valFromOption(value)
25
+ ];
26
+ }
27
+
28
+ }));
29
+ if (v !== undefined) {
30
+ return Caml_option.valFromOption(v);
31
+ } else {
32
+ return {};
33
+ }
34
+ }
20
35
 
21
- return newObj;
22
- });
36
+ function internal_removeUndefinedAndConvertNullsRaw(record) {
37
+ return internal_keepMapFieldsRaw(record, (function (param) {
38
+ var value = param[1];
39
+ var key = param[0];
40
+ var match = Caml_obj.caml_equal(value, Caml_option.some(undefined));
41
+ if (value !== undefined) {
42
+ return [
43
+ key,
44
+ Caml_option.valFromOption(value)
45
+ ];
46
+ } else if (match) {
47
+ return [
48
+ key,
49
+ null
50
+ ];
51
+ } else {
52
+ return ;
53
+ }
54
+ }));
55
+ }
23
56
 
24
57
  function internal_useConvertedValue(convert, v) {
25
58
  return React.useMemo((function () {
@@ -38,5 +71,6 @@ function internal_nullableToOptionalExnHandler(x) {
38
71
 
39
72
  exports.internal_useConvertedValue = internal_useConvertedValue;
40
73
  exports.internal_cleanObjectFromUndefinedRaw = internal_cleanObjectFromUndefinedRaw;
74
+ exports.internal_removeUndefinedAndConvertNullsRaw = internal_removeUndefinedAndConvertNullsRaw;
41
75
  exports.internal_nullableToOptionalExnHandler = internal_nullableToOptionalExnHandler;
42
76
  /* react Not a pure module */
@@ -1,23 +1,30 @@
1
- // We occasionally have to remove undefined keys from objects, something I haven't figured out how to do with pure BuckleScript
2
- let internal_cleanObjectFromUndefinedRaw = %raw(
3
- `
4
- function (obj) {
5
- if (!obj) {
6
- return obj;
7
- }
8
-
9
- var newObj = {};
10
-
11
- Object.keys(obj).forEach(function(key) {
12
- if (typeof obj[key] !== 'undefined') {
13
- newObj[key] = obj[key];
14
- }
15
- });
1
+ let internal_keepMapFieldsRaw = (record, f) =>
2
+ record
3
+ ->Obj.magic
4
+ ->Belt.Option.map(obj => obj->Js.Dict.entries->Belt.Array.keepMap(f)->Js.Dict.fromArray)
5
+ ->Obj.magic
16
6
 
17
- return newObj;
7
+ // we need to do this until we can use @obj on record types
8
+ // see https://github.com/rescript-lang/rescript-compiler/pull/5253
9
+ let internal_cleanObjectFromUndefinedRaw = record =>
10
+ switch internal_keepMapFieldsRaw(record, ((key, value)) => {
11
+ switch value {
12
+ | Some(value) => Some((key, value))
13
+ | None => None
14
+ }
15
+ }) {
16
+ | None => /* Relay expects an empty object, not undefined */ %raw(json`{}`)
17
+ | Some(v) => v
18
18
  }
19
- `
20
- )
19
+
20
+ let internal_removeUndefinedAndConvertNullsRaw = record =>
21
+ internal_keepMapFieldsRaw(record, ((key, value)) => {
22
+ switch (value, value == Some(None)) {
23
+ | (Some(value), _) => Some((key, Js.Nullable.return(value)))
24
+ | (_, true) => Some((key, Js.Nullable.null))
25
+ | (None, _) => None
26
+ }
27
+ })
21
28
 
22
29
  let internal_useConvertedValue = (convert, v) => React.useMemo1(() => convert(v), [v])
23
30
 
@@ -1,5 +1,6 @@
1
1
  let internal_useConvertedValue: ('a => 'a, 'a) => 'a
2
2
  let internal_cleanObjectFromUndefinedRaw: 't => 't
3
+ let internal_removeUndefinedAndConvertNullsRaw: 't => 't
3
4
  let internal_nullableToOptionalExnHandler: option<option<'b> => 'a> => option<
4
5
  Js.Nullable.t<'b> => 'a,
5
6
  >