rescript-relay 4.0.0 → 4.2.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,32 @@
1
1
  # master
2
2
 
3
+ # 4.2.0
4
+
5
+ - Simplify `missingFieldHandlers`. https://github.com/zth/rescript-relay/pull/589
6
+ - Fix behavior of `refetchVariables` on optional variables. https://github.com/zth/rescript-relay/pull/588
7
+ - Support `@exhaustive` on inline fragments.
8
+
9
+ # 4.1.0
10
+
11
+ - Add support for `autoExhaustiveTypes` config and a `@nonExhaustive` directive to control automatic exhaustive checks for unions/interfaces.
12
+
13
+ - Add React-free mode support and split React APIs into `RescriptRelayReact`.
14
+
15
+ - New compiler config: `rescriptRelayMode: "Default" | "NonReact"` (defaults to `"Default"`).
16
+ - PPX `-non-react`
17
+ - Mark `@rescript/react` and `react-relay` as optional peer deps so non‑React usage does not require them.
18
+
19
+ - BREAKING: Move all React-specific APIs out of `RescriptRelay` into `RescriptRelayReact`.
20
+
21
+ - `RescriptRelay.Context.Provider` -> `RescriptRelayReact.Context.Provider`
22
+ - `RescriptRelay.useEnvironmentFromContext` -> `RescriptRelayReact.useEnvironmentFromContext`
23
+ - `RescriptRelay.useSubscribeToInvalidationState` -> `RescriptRelayReact.useSubscribeToInvalidationState`
24
+
25
+ Migration:
26
+
27
+ - Update imports/usages in app code to reference `RescriptRelayReact` for the APIs listed above.
28
+ - For non‑React usage, set `rescriptRelayMode: "NonReact"` in `relay.config.js` and pass `-non-react` to the PPX.
29
+
3
30
  # 4.0.0
4
31
 
5
32
  - Support `@exhaustive` on interfaces as well.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rescript-relay",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "main": "src/RescriptRelay.res",
5
5
  "license": "MIT",
6
6
  "author": "Gabriel Nordeborn",
@@ -56,7 +56,7 @@
56
56
  "react-dom": "18.2.0",
57
57
  "react-relay": "20.1.1",
58
58
  "relay-runtime": "20.1.1",
59
- "rescript": "12.0.0-rc.3"
59
+ "rescript": "12.0.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@rescript/react": ">=0.13.0",
@@ -64,6 +64,14 @@
64
64
  "relay-runtime": "20.1.1",
65
65
  "rescript": "^12.0.0-0"
66
66
  },
67
+ "peerDependenciesMeta": {
68
+ "@rescript/react": {
69
+ "optional": true
70
+ },
71
+ "react-relay": {
72
+ "optional": true
73
+ }
74
+ },
67
75
  "dependencies": {
68
76
  "detect-libc": "^2.0.1"
69
77
  }
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
@@ -1,15 +1,13 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
  'use strict';
3
3
 
4
- let React = require("react");
5
4
  let Utils = require("./utils");
6
- let ReactRelay = require("react-relay");
7
5
  let Stdlib_Option = require("@rescript/runtime/lib/js/Stdlib_Option.js");
8
6
  let RelayRuntime = require("relay-runtime");
9
7
  let Primitive_option = require("@rescript/runtime/lib/js/Primitive_option.js");
10
8
  let Primitive_exceptions = require("@rescript/runtime/lib/js/Primitive_exceptions.js");
11
- let LiveResolverStore = require("relay-runtime/lib/store/live-resolvers/LiveResolverStore").default;
12
- let LiveResolverStore$1 = require("relay-runtime/lib/store/live-resolvers/LiveResolverStore");
9
+ let LiveResolverStore = require("relay-runtime/lib/store/live-resolvers/LiveResolverStore");
10
+ let LiveResolverStore$1 = require("relay-runtime/lib/store/live-resolvers/LiveResolverStore").default;
13
11
 
14
12
  function toOption(t) {
15
13
  if (t.ok === true) {
@@ -79,31 +77,6 @@ let RecordSourceSelectorProxy = {
79
77
 
80
78
  let ReadOnlyRecordSourceProxy = {};
81
79
 
82
- function unwrapNormalizationArgument(wrapped) {
83
- let match = wrapped.kind;
84
- if (match === "Literal") {
85
- return {
86
- TAG: "Literal",
87
- _0: wrapped
88
- };
89
- } else if (match === "ListValue") {
90
- return {
91
- TAG: "ListValue",
92
- _0: wrapped
93
- };
94
- } else if (match === "ObjectValue") {
95
- return {
96
- TAG: "ObjectValue",
97
- _0: wrapped
98
- };
99
- } else {
100
- return {
101
- TAG: "Variable",
102
- _0: wrapped
103
- };
104
- }
105
- }
106
-
107
80
  function makeScalarMissingFieldHandler(handle) {
108
81
  return {
109
82
  kind: "scalar",
@@ -126,21 +99,23 @@ function makePluralLinkedMissingFieldHandler(handle) {
126
99
  }
127
100
 
128
101
  let MissingFieldHandler = {
129
- unwrapNormalizationArgument: unwrapNormalizationArgument,
130
102
  makeScalarMissingFieldHandler: makeScalarMissingFieldHandler,
131
103
  makeLinkedMissingFieldHandler: makeLinkedMissingFieldHandler,
132
104
  makePluralLinkedMissingFieldHandler: makePluralLinkedMissingFieldHandler
133
105
  };
134
106
 
135
- let nodeInterfaceMissingFieldHandler = makeLinkedMissingFieldHandler((field, record, args, _store) => {
136
- let match = field.name;
137
- let match$1 = args.id;
138
- if ((record == null) || match !== "node" || record.getType() !== RelayRuntime.ROOT_TYPE || (match$1 == null)) {
139
- return;
140
- } else {
141
- return Primitive_option.some(match$1);
107
+ let nodeInterfaceMissingFieldHandler = {
108
+ kind: "linked",
109
+ handle: (field, record, args, _store) => {
110
+ let match = field.name;
111
+ let match$1 = args.id;
112
+ if ((record == null) || match !== "node" || record.getType() !== RelayRuntime.ROOT_TYPE) {
113
+ return;
114
+ } else {
115
+ return match$1;
116
+ }
142
117
  }
143
- });
118
+ };
144
119
 
145
120
  let ConnectionHandler = {};
146
121
 
@@ -229,14 +204,14 @@ function make(source, gcReleaseBufferSize, queryCacheExpirationTime) {
229
204
  }
230
205
 
231
206
  function makeLiveStore(source, gcReleaseBufferSize, queryCacheExpirationTime) {
232
- return new LiveResolverStore(source, {
207
+ return new LiveResolverStore$1(source, {
233
208
  gcReleaseBufferSize: gcReleaseBufferSize,
234
209
  queryCacheExpirationTime: queryCacheExpirationTime
235
210
  });
236
211
  }
237
212
 
238
213
  function _makeLiveStoreCjs(source, gcReleaseBufferSize, queryCacheExpirationTime) {
239
- return new LiveResolverStore$1(source, {
214
+ return new LiveResolverStore(source, {
240
215
  gcReleaseBufferSize: gcReleaseBufferSize,
241
216
  queryCacheExpirationTime: queryCacheExpirationTime
242
217
  });
@@ -295,68 +270,6 @@ let Environment = {
295
270
  invalidateAllOfConnection: invalidateAllOfConnection
296
271
  };
297
272
 
298
- function RescriptRelay$Context$Provider(props) {
299
- let provider = ReactRelay.ReactRelayContext.Provider;
300
- return React.createElement(provider, {
301
- value: {
302
- environment: props.environment
303
- },
304
- children: props.children
305
- });
306
- }
307
-
308
- let Provider = {
309
- make: RescriptRelay$Context$Provider
310
- };
311
-
312
- let Context = {
313
- Provider: Provider
314
- };
315
-
316
- let EnvironmentNotFoundInContext = /* @__PURE__ */Primitive_exceptions.create("RescriptRelay.EnvironmentNotFoundInContext");
317
-
318
- function useEnvironmentFromContext() {
319
- let context = React.useContext(ReactRelay.ReactRelayContext);
320
- if (context !== undefined) {
321
- return Primitive_option.valFromOption(context).environment;
322
- }
323
- throw {
324
- RE_EXN_ID: EnvironmentNotFoundInContext,
325
- Error: new Error()
326
- };
327
- }
328
-
329
- function MakeLoadQuery(C) {
330
- let load = (environment, variables, fetchPolicy, fetchKey, networkCacheConfig) => ReactRelay.loadQuery(environment, C.query, C.convertVariables(variables), {
331
- fetchKey: fetchKey,
332
- fetchPolicy: fetchPolicy,
333
- networkCacheConfig: networkCacheConfig
334
- });
335
- let queryRefToObservable = token => Primitive_option.fromNullable(token.source);
336
- let queryRefToPromise = token => new Promise((resolve, param) => {
337
- let o = queryRefToObservable(token);
338
- if (o !== undefined) {
339
- Primitive_option.valFromOption(o).subscribe({
340
- complete: () => resolve({
341
- TAG: "Ok",
342
- _0: undefined
343
- })
344
- });
345
- return;
346
- } else {
347
- return resolve({
348
- TAG: "Error",
349
- _0: undefined
350
- });
351
- }
352
- });
353
- return {
354
- load: load,
355
- queryRefToObservable: queryRefToObservable,
356
- queryRefToPromise: queryRefToPromise
357
- };
358
- }
359
-
360
273
  let Mutation_failed = /* @__PURE__ */Primitive_exceptions.create("RescriptRelay.Mutation_failed");
361
274
 
362
275
  exports.CatchResult = CatchResult;
@@ -374,9 +287,5 @@ exports.Store = Store;
374
287
  exports.Disposable = Disposable;
375
288
  exports.RelayFieldLogger = RelayFieldLogger;
376
289
  exports.Environment = Environment;
377
- exports.Context = Context;
378
- exports.EnvironmentNotFoundInContext = EnvironmentNotFoundInContext;
379
- exports.useEnvironmentFromContext = useEnvironmentFromContext;
380
290
  exports.Mutation_failed = Mutation_failed;
381
- exports.MakeLoadQuery = MakeLoadQuery;
382
- /* nodeInterfaceMissingFieldHandler Not a pure module */
291
+ /* ./utils Not a pure module */
@@ -347,78 +347,65 @@ module ReadOnlyRecordSourceProxy = {
347
347
  }
348
348
 
349
349
  module MissingFieldHandler = {
350
- @@warning("-30")
351
- type t
352
-
353
- type normalizationArgumentWrapped = {kind: [#ListValue | #Literal | #ObjectValue | #Variable]}
354
-
355
- type rec normalizationListValueArgument = {
356
- name: string,
357
- items: array<Nullable.t<normalizationArgumentWrapped>>,
358
- }
359
- and normalizationLiteralArgument = {
360
- name: string,
361
- @as("type") type_: Nullable.t<string>,
362
- value: JSON.t,
363
- }
364
- and normalizationObjectValueArgument = {
365
- name: string,
366
- fields: Nullable.t<array<normalizationArgumentWrapped>>,
367
- }
368
- and normalizationVariableArgument = {
369
- name: string,
370
- @as("type") type_: Nullable.t<string>,
371
- variableName: string,
372
- }
373
-
374
- type normalizationArgument =
375
- | ListValue(normalizationListValueArgument)
376
- | Literal(normalizationLiteralArgument)
377
- | ObjectValue(normalizationObjectValueArgument)
378
- | Variable(normalizationVariableArgument)
379
-
380
- let unwrapNormalizationArgument = wrapped =>
381
- switch wrapped.kind {
382
- | #ListValue => ListValue(Obj.magic(wrapped))
383
- | #Literal => Literal(Obj.magic(wrapped))
384
- | #ObjectValue => ObjectValue(Obj.magic(wrapped))
385
- | #Variable => Variable(Obj.magic(wrapped))
386
- }
350
+ @tag("kind")
351
+ type rec normalizationArgument =
352
+ | ListValue({name: string, items: array<null<normalizationArgument>>})
353
+ | Literal({name: string, @as("type") type_: nullable<string>, value: JSON.t})
354
+ | ObjectValue({name: string, fields: array<normalizationArgument>})
355
+ | Variable({name: string, @as("type") type_: nullable<string>, variableName: string})
387
356
 
388
357
  type normalizationScalarField = {
389
- alias: Nullable.t<string>,
358
+ alias: nullable<string>,
390
359
  name: string,
391
- args: Nullable.t<array<normalizationArgumentWrapped>>,
392
- storageKey: Nullable.t<string>,
360
+ args: nullable<array<normalizationArgument>>,
361
+ storageKey: nullable<string>,
393
362
  }
394
363
 
395
- let makeScalarMissingFieldHandler = handle =>
396
- Obj.magic({
397
- "kind": #scalar,
398
- "handle": handle,
399
- })
400
-
401
364
  type normalizationLinkedField = {
402
- alias: Nullable.t<string>,
365
+ alias: nullable<string>,
403
366
  name: string,
404
- storageKey: Nullable.t<string>,
405
- args: Nullable.t<array<normalizationArgument>>,
406
- concreteType: Nullable.t<string>,
367
+ storageKey: nullable<string>,
368
+ args: nullable<array<normalizationArgument>>,
369
+ concreteType: nullable<string>,
407
370
  plural: bool,
408
371
  selections: array<JSON.t>,
409
372
  }
410
373
 
411
- let makeLinkedMissingFieldHandler = handle =>
412
- Obj.magic({
413
- "kind": #linked,
414
- "handle": handle,
415
- })
416
-
417
- let makePluralLinkedMissingFieldHandler = handle =>
418
- Obj.magic({
419
- "kind": #pluralLinked,
420
- "handle": handle,
421
- })
374
+ @tag("kind")
375
+ type rec t =
376
+ | @as("scalar")
377
+ Scalar({
378
+ handle: (
379
+ normalizationScalarField,
380
+ nullable<'record>,
381
+ 'args,
382
+ ReadOnlyRecordSourceProxy.t,
383
+ ) => nullable<'scalarValue>,
384
+ }): t
385
+ | @as("linked")
386
+ Linked({
387
+ handle: (
388
+ normalizationLinkedField,
389
+ nullable<'record>,
390
+ 'args,
391
+ ReadOnlyRecordSourceProxy.t,
392
+ ) => nullable<dataId>,
393
+ }): t
394
+ | @as("pluralLinked")
395
+ PluralLinked({
396
+ handle: (
397
+ normalizationLinkedField,
398
+ nullable<'record>,
399
+ 'args,
400
+ ReadOnlyRecordSourceProxy.t,
401
+ ) => nullable<array<nullable<dataId>>>,
402
+ }): t
403
+
404
+ let makeScalarMissingFieldHandler = handle => Scalar({handle: handle})
405
+
406
+ let makeLinkedMissingFieldHandler = handle => Linked({handle: handle})
407
+
408
+ let makePluralLinkedMissingFieldHandler = handle => PluralLinked({handle: handle})
422
409
  }
423
410
 
424
411
  // This handler below enables automatic resolution of all cached items through the Node interface
@@ -428,9 +415,9 @@ let nodeInterfaceMissingFieldHandler = MissingFieldHandler.makeLinkedMissingFiel
428
415
  args,
429
416
  _store,
430
417
  ) =>
431
- switch (Nullable.toOption(record), field["name"], Nullable.toOption(args["id"])) {
432
- | (Some(record), "node", argsId) if record->RecordProxy.getType == storeRootType => argsId
433
- | _ => None
418
+ switch (record, field.name, args["id"]) {
419
+ | (Value(record), "node", argsId) if record->RecordProxy.getType == storeRootType => argsId
420
+ | _ => undefined
434
421
  }
435
422
  )
436
423
 
@@ -827,33 +814,7 @@ module Environment = {
827
814
  }
828
815
  }
829
816
 
830
- module Context = {
831
- type t
832
-
833
- type contextShape = {"environment": Environment.t}
834
-
835
- @module("react-relay")
836
- external context: React.Context.t<option<contextShape>> = "ReactRelayContext"
837
-
838
- module Provider = {
839
- @react.component
840
- let make = (~environment: Environment.t, ~children) => {
841
- let provider = React.Context.provider(context)
842
- React.createElement(provider, {value: Some({"environment": environment}), children})
843
- }
844
- }
845
- }
846
-
847
- exception EnvironmentNotFoundInContext
848
-
849
- let useEnvironmentFromContext = () => {
850
- let context = React.useContext(Context.context)
851
-
852
- switch context {
853
- | Some(ctx) => ctx["environment"]
854
- | None => throw(EnvironmentNotFoundInContext)
855
- }
856
- }
817
+ /* React Context moved to RescriptRelayReact */
857
818
 
858
819
  type fetchPolicy =
859
820
  | @as("store-only") StoreOnly
@@ -870,69 +831,7 @@ type fetchQueryOptions = {
870
831
  fetchPolicy?: fetchPolicy,
871
832
  }
872
833
 
873
- type loadQueryConfig = {
874
- fetchKey: option<string>,
875
- fetchPolicy: option<fetchPolicy>,
876
- networkCacheConfig: option<cacheConfig>,
877
- }
878
-
879
- @module("react-relay")
880
- external loadQuery: (Environment.t, queryNode<'a>, 'variables, loadQueryConfig) => 'queryResponse =
881
- "loadQuery"
882
-
883
- module type MakeLoadQueryConfig = {
884
- type variables
885
- type loadedQueryRef
886
- type response
887
- type node
888
- let query: queryNode<node>
889
- let convertVariables: variables => variables
890
- }
891
-
892
- module MakeLoadQuery = (C: MakeLoadQueryConfig) => {
893
- let load: (
894
- ~environment: Environment.t,
895
- ~variables: C.variables,
896
- ~fetchPolicy: fetchPolicy=?,
897
- ~fetchKey: string=?,
898
- ~networkCacheConfig: cacheConfig=?,
899
- ) => C.loadedQueryRef = (
900
- ~environment,
901
- ~variables,
902
- ~fetchPolicy=?,
903
- ~fetchKey=?,
904
- ~networkCacheConfig=?,
905
- ) =>
906
- loadQuery(
907
- environment,
908
- C.query,
909
- variables->C.convertVariables,
910
- {
911
- fetchKey,
912
- fetchPolicy,
913
- networkCacheConfig,
914
- },
915
- )
916
-
917
- type rawPreloadToken<'response> = {source: Nullable.t<Observable.t<'response>>}
918
- external tokenToRaw: C.loadedQueryRef => rawPreloadToken<C.response> = "%identity"
919
-
920
- let queryRefToObservable = token => {
921
- let raw = token->tokenToRaw
922
- raw.source->Nullable.toOption
923
- }
924
-
925
- let queryRefToPromise = token => {
926
- Promise.make((resolve, _) => {
927
- switch token->queryRefToObservable {
928
- | None => resolve(Error())
929
- | Some(o) =>
930
- open Observable
931
- let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok())))
932
- }
933
- })
934
- }
935
- }
834
+ /* React loadQuery helpers moved to RescriptRelayReact */
936
835
 
937
836
  type mutationError = {message: string}
938
837
 
@@ -944,6 +843,4 @@ external commitLocalUpdate: (
944
843
  ~updater: RecordSourceSelectorProxy.t => unit,
945
844
  ) => unit = "commitLocalUpdate"
946
845
 
947
- @module("react-relay")
948
- external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
949
- "useSubscribeToInvalidationState"
846
+ /* React invalidation subscribe moved to RescriptRelayReact */
@@ -635,68 +635,75 @@ module ReadOnlyRecordSourceProxy: {
635
635
 
636
636
  Feed a list of missing field handlers into `Environment.make` if you want to use them.*/
637
637
  module MissingFieldHandler: {
638
- @@warning("-30")
639
-
640
- /**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/).*/
641
- type t
642
-
643
- type normalizationArgumentWrapped = {kind: [#ListValue | #Literal | #ObjectValue | #Variable]}
638
+ @tag("kind")
639
+ type rec normalizationArgument =
640
+ | ListValue({name: string, items: array<null<normalizationArgument>>})
641
+ | Literal({name: string, @as("type") type_: nullable<string>, value: JSON.t})
642
+ | ObjectValue({name: string, fields: array<normalizationArgument>})
643
+ | Variable({name: string, @as("type") type_: nullable<string>, variableName: string})
644
644
 
645
- type rec normalizationListValueArgument = {
646
- name: string,
647
- items: array<Nullable.t<normalizationArgumentWrapped>>,
648
- }
649
- and normalizationLiteralArgument = {
650
- name: string,
651
- @as("type") type_: Nullable.t<string>,
652
- value: JSON.t,
653
- }
654
- and normalizationObjectValueArgument = {
655
- name: string,
656
- fields: Nullable.t<array<normalizationArgumentWrapped>>,
657
- }
658
- and normalizationVariableArgument = {
645
+ type normalizationScalarField = {
646
+ alias: nullable<string>,
659
647
  name: string,
660
- @as("type") type_: Nullable.t<string>,
661
- variableName: string,
648
+ args: nullable<array<normalizationArgument>>,
649
+ storageKey: nullable<string>,
662
650
  }
663
651
 
664
- type normalizationArgument =
665
- | ListValue(normalizationListValueArgument)
666
- | Literal(normalizationLiteralArgument)
667
- | ObjectValue(normalizationObjectValueArgument)
668
- | Variable(normalizationVariableArgument)
669
-
670
- let unwrapNormalizationArgument: normalizationArgumentWrapped => normalizationArgument
671
-
672
- type normalizationScalarField = {
673
- alias: Nullable.t<string>,
652
+ type normalizationLinkedField = {
653
+ alias: nullable<string>,
674
654
  name: string,
675
- args: Nullable.t<array<normalizationArgumentWrapped>>,
676
- storageKey: Nullable.t<string>,
655
+ storageKey: nullable<string>,
656
+ args: nullable<array<normalizationArgument>>,
657
+ concreteType: nullable<string>,
658
+ plural: bool,
659
+ selections: array<JSON.t>,
677
660
  }
678
661
 
679
- /**Make a `MissingFieldHandler.t` for scalar fields. Give this a handler function that returns `Js.null` (to indicate that data exists but is null), `Js.undefined` (to indicate data is still missing), or a scalar value (to indicate that the value exists even though it's not in the cache, and is the value you send back).*/
662
+ /**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/).*/
663
+ @tag("kind")
664
+ type rec t =
665
+ /** a `MissingFieldHandler.t` for scalar fields. Give this a handler function that returns `null` (to indicate that data exists but is null), `undefined` (to indicate data is still missing), or a scalar value (to indicate that the value exists even though it's not in the cache, and is the value you send back).*/
666
+ | @as("scalar")
667
+ Scalar({
668
+ handle: (
669
+ normalizationScalarField,
670
+ nullable<'record>,
671
+ 'args,
672
+ ReadOnlyRecordSourceProxy.t,
673
+ ) => nullable<'scalarValue>,
674
+ }): t
675
+ /** a `MissingFieldHandler.t` for linked fields (other objects/records). Give this a handler function that returns `null` (to indicate that the link exists but the linked record is null), `undefined` (to indicate data is still missing), or a `dataId` of the record that is linked at this field.*/
676
+ | @as("linked")
677
+ Linked({
678
+ handle: (
679
+ normalizationLinkedField,
680
+ nullable<'record>,
681
+ 'args,
682
+ ReadOnlyRecordSourceProxy.t,
683
+ ) => nullable<dataId>,
684
+ }): t
685
+ /** a `MissingFieldHandler.t` for lists of linked fields (other objects/records). Give this a handler function that returns `null` (to indicate that the link exists but the linked array of records is null), `undefined` (to indicate data is still missing), or an array of `nullable<dataId>` where the `dataId`'s are the linked records/objects.*/
686
+ | @as("pluralLinked")
687
+ PluralLinked({
688
+ handle: (
689
+ normalizationLinkedField,
690
+ nullable<'record>,
691
+ 'args,
692
+ ReadOnlyRecordSourceProxy.t,
693
+ ) => nullable<array<nullable<dataId>>>,
694
+ }): t
695
+
696
+ /**Make a `MissingFieldHandler.t` for scalar fields. Give this a handler function that returns `null` (to indicate that data exists but is null), `undefined` (to indicate data is still missing), or a scalar value (to indicate that the value exists even though it's not in the cache, and is the value you send back).*/
680
697
  let makeScalarMissingFieldHandler: (
681
698
  (
682
699
  normalizationScalarField,
683
700
  Nullable.t<'record>,
684
701
  'args,
685
702
  ReadOnlyRecordSourceProxy.t,
686
- ) => 'scalarValue
703
+ ) => Nullable.t<'scalarValue>
687
704
  ) => t
688
705
 
689
- type normalizationLinkedField = {
690
- alias: Nullable.t<string>,
691
- name: string,
692
- storageKey: Nullable.t<string>,
693
- args: Nullable.t<array<normalizationArgument>>,
694
- concreteType: Nullable.t<string>,
695
- plural: bool,
696
- selections: array<JSON.t>,
697
- }
698
-
699
- /**Make a `MissingFieldHandler.t` for linked fields (other objects/records). Give this a handler function that returns `Js.null` (to indicate that the link exists but the linked record is null), `Js.undefined` (to indicate data is still missing), or a `dataId` of the record that is linked at this field.*/
706
+ /**Make a `MissingFieldHandler.t` for linked fields (other objects/records). Give this a handler function that returns `null` (to indicate that the link exists but the linked record is null), `undefined` (to indicate data is still missing), or a `dataId` of the record that is linked at this field.*/
700
707
  let makeLinkedMissingFieldHandler: (
701
708
  (
702
709
  normalizationLinkedField,
@@ -706,7 +713,7 @@ module MissingFieldHandler: {
706
713
  ) => Nullable.t<dataId>
707
714
  ) => t
708
715
 
709
- /**Make a `MissingFieldHandler.t` for lists of linked fields (other objects/records). Give this a handler function that returns `Js.null` (to indicate that the link exists but the linked record is null), `Js.undefined` (to indicate data is still missing), or an array of `Js.Nullable.t<dataId>` where the `dataId`'s are the linked records/objects.*/
716
+ /**Make a `MissingFieldHandler.t` for lists of linked fields (other objects/records). Give this a handler function that returns `null` (to indicate that the link exists but the linked array of records is null), `undefined` (to indicate data is still missing), or an array of `nullable<dataId>` where the `dataId`'s are the linked records/objects.*/
710
717
  let makePluralLinkedMissingFieldHandler: (
711
718
  (
712
719
  normalizationLinkedField,
@@ -1534,34 +1541,7 @@ type fetchQueryFetchPolicy =
1534
1541
  /**An error from a mutation.*/
1535
1542
  type mutationError = {message: string}
1536
1543
 
1537
- /**Context provider for the Relay environment.*/
1538
- module Context: {
1539
- /**Type representing the context.*/
1540
- type t
1541
-
1542
- /**The expected shape of the context.*/
1543
- type contextShape = {"environment": Environment.t}
1544
-
1545
- /**The actual React context coming from Relay.*/
1546
- @module("react-relay")
1547
- external context: React.Context.t<option<contextShape>> = "ReactRelayContext"
1548
-
1549
- /**The context provider you wrap your app in and pass your `Environment` for Relay to work.*/
1550
- module Provider: {
1551
- /**The React component you wrap your app in and pass your `Environment` for Relay to work.*/
1552
- type props<'environment, 'children> = {
1553
- environment: 'environment,
1554
- children: 'children,
1555
- }
1556
- let make: props<Environment.t, React.element> => React.element
1557
- }
1558
- }
1559
-
1560
- /**An exception saying that the environment could not be found in the context. Means you forgot to wrap your app in `<RescriptRelay.Context.Provider environment=RelayEnv.environment>`*/
1561
- exception EnvironmentNotFoundInContext
1562
-
1563
- /**Hook for getting the current environment from context.*/
1564
- let useEnvironmentFromContext: unit => Environment.t
1544
+ /* React Context moved to RescriptRelayReact */
1565
1545
 
1566
1546
  /**An exception detailing that a mutation failed.*/
1567
1547
  exception Mutation_failed(array<mutationError>)
@@ -1603,38 +1583,7 @@ external commitLocalUpdate: (
1603
1583
  ~updater: RecordSourceSelectorProxy.t => unit,
1604
1584
  ) => unit = "commitLocalUpdate"
1605
1585
 
1606
- /**
1607
- Subscribes to invalidation events for specific records.
1608
-
1609
- Executes a callback whenever any of the specified records are invalidated.
1610
- Useful for triggering refetches or UI updates when cached data becomes stale.
1611
-
1612
- ## Parameters
1613
- - Array of `dataId`s to watch for invalidation
1614
- - Callback function executed when any watched record is invalidated
1615
-
1616
- ## Examples
1617
-
1618
- ```rescript
1619
- // Watch for user invalidation and refetch
1620
- let disposable = RescriptRelay.useSubscribeToInvalidationState(
1621
- [user.__id],
1622
- () => {
1623
- // Refetch user data when invalidated
1624
- UserQuery.fetchPromised(~environment, ~variables={id: user.id})
1625
- ->Promise.done
1626
- }
1627
- )
1628
-
1629
- // Clean up subscription
1630
- React.useEffect1(() => {
1631
- Some(() => disposable->RescriptRelay.Disposable.dispose)
1632
- }, [disposable])
1633
- ```
1634
- */
1635
- @module("react-relay")
1636
- external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
1637
- "useSubscribeToInvalidationState"
1586
+ /* React invalidation subscribe moved to RescriptRelayReact */
1638
1587
 
1639
1588
  /**Options valid when fetching a query outside of React's render method (like when using `Query.fetch`).*/
1640
1589
  type fetchQueryOptions = {
@@ -1642,35 +1591,4 @@ type fetchQueryOptions = {
1642
1591
  fetchPolicy?: fetchPolicy,
1643
1592
  }
1644
1593
 
1645
- type loadQueryConfig = {
1646
- fetchKey: option<string>,
1647
- fetchPolicy: option<fetchPolicy>,
1648
- networkCacheConfig: option<cacheConfig>,
1649
- }
1650
-
1651
- @module("react-relay")
1652
- external loadQuery: (Environment.t, queryNode<'a>, 'variables, loadQueryConfig) => 'queryResponse =
1653
- "loadQuery"
1654
-
1655
- module type MakeLoadQueryConfig = {
1656
- type variables
1657
- type loadedQueryRef
1658
- type response
1659
- type node
1660
- let query: queryNode<node>
1661
- let convertVariables: variables => variables
1662
- }
1663
-
1664
- module MakeLoadQuery: (C: MakeLoadQueryConfig) =>
1665
- {
1666
- let load: (
1667
- ~environment: Environment.t,
1668
- ~variables: C.variables,
1669
- ~fetchPolicy: fetchPolicy=?,
1670
- ~fetchKey: string=?,
1671
- ~networkCacheConfig: cacheConfig=?,
1672
- ) => C.loadedQueryRef
1673
-
1674
- let queryRefToObservable: C.loadedQueryRef => option<Observable.t<C.response>>
1675
- let queryRefToPromise: C.loadedQueryRef => promise<Belt.Result.t<unit, unit>>
1676
- }
1594
+ /* React loadQuery helpers moved to RescriptRelayReact */
@@ -0,0 +1,75 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ let React = require("react");
5
+ let ReactRelay = require("react-relay");
6
+ let Primitive_option = require("@rescript/runtime/lib/js/Primitive_option.js");
7
+ let Primitive_exceptions = require("@rescript/runtime/lib/js/Primitive_exceptions.js");
8
+
9
+ function RescriptRelayReact$Context$Provider(props) {
10
+ let provider = ReactRelay.ReactRelayContext.Provider;
11
+ return React.createElement(provider, {
12
+ value: {
13
+ environment: props.environment
14
+ },
15
+ children: props.children
16
+ });
17
+ }
18
+
19
+ let Provider = {
20
+ make: RescriptRelayReact$Context$Provider
21
+ };
22
+
23
+ let Context = {
24
+ Provider: Provider
25
+ };
26
+
27
+ let EnvironmentNotFoundInContext = /* @__PURE__ */Primitive_exceptions.create("RescriptRelayReact.EnvironmentNotFoundInContext");
28
+
29
+ function useEnvironmentFromContext() {
30
+ let context = React.useContext(ReactRelay.ReactRelayContext);
31
+ if (context !== undefined) {
32
+ return Primitive_option.valFromOption(context).environment;
33
+ }
34
+ throw {
35
+ RE_EXN_ID: EnvironmentNotFoundInContext,
36
+ Error: new Error()
37
+ };
38
+ }
39
+
40
+ function MakeLoadQuery(C) {
41
+ let load = (environment, variables, fetchPolicy, fetchKey, networkCacheConfig) => ReactRelay.loadQuery(environment, C.query, C.convertVariables(variables), {
42
+ fetchKey: fetchKey,
43
+ fetchPolicy: fetchPolicy,
44
+ networkCacheConfig: networkCacheConfig
45
+ });
46
+ let queryRefToObservable = token => Primitive_option.fromNullable(token.source);
47
+ let queryRefToPromise = token => new Promise((resolve, param) => {
48
+ let o = queryRefToObservable(token);
49
+ if (o !== undefined) {
50
+ Primitive_option.valFromOption(o).subscribe({
51
+ complete: () => resolve({
52
+ TAG: "Ok",
53
+ _0: undefined
54
+ })
55
+ });
56
+ return;
57
+ } else {
58
+ return resolve({
59
+ TAG: "Error",
60
+ _0: undefined
61
+ });
62
+ }
63
+ });
64
+ return {
65
+ load: load,
66
+ queryRefToObservable: queryRefToObservable,
67
+ queryRefToPromise: queryRefToPromise
68
+ };
69
+ }
70
+
71
+ exports.Context = Context;
72
+ exports.EnvironmentNotFoundInContext = EnvironmentNotFoundInContext;
73
+ exports.useEnvironmentFromContext = useEnvironmentFromContext;
74
+ exports.MakeLoadQuery = MakeLoadQuery;
75
+ /* react Not a pure module */
@@ -0,0 +1,94 @@
1
+ open RescriptRelay
2
+
3
+ module Context = {
4
+ type t
5
+ type contextShape = {"environment": Environment.t}
6
+ @module("react-relay")
7
+ external context: React.Context.t<option<contextShape>> = "ReactRelayContext"
8
+
9
+ module Provider = {
10
+ @react.component
11
+ let make = (~environment: Environment.t, ~children) => {
12
+ let provider = React.Context.provider(context)
13
+ React.createElement(provider, {value: Some({"environment": environment}), children})
14
+ }
15
+ }
16
+ }
17
+
18
+ exception EnvironmentNotFoundInContext
19
+
20
+ let useEnvironmentFromContext = () => {
21
+ let context = React.useContext(Context.context)
22
+ switch context {
23
+ | Some(ctx) => ctx["environment"]
24
+ | None => throw(EnvironmentNotFoundInContext)
25
+ }
26
+ }
27
+
28
+ type loadQueryConfig = {
29
+ fetchKey: option<string>,
30
+ fetchPolicy: option<fetchPolicy>,
31
+ networkCacheConfig: option<cacheConfig>,
32
+ }
33
+
34
+ @module("react-relay")
35
+ external loadQuery: (Environment.t, queryNode<'a>, 'variables, loadQueryConfig) => 'queryResponse =
36
+ "loadQuery"
37
+
38
+ module type MakeLoadQueryConfig = {
39
+ type variables
40
+ type loadedQueryRef
41
+ type response
42
+ type node
43
+ let query: queryNode<node>
44
+ let convertVariables: variables => variables
45
+ }
46
+
47
+ module MakeLoadQuery = (C: MakeLoadQueryConfig) => {
48
+ let load: (
49
+ ~environment: Environment.t,
50
+ ~variables: C.variables,
51
+ ~fetchPolicy: fetchPolicy=?,
52
+ ~fetchKey: string=?,
53
+ ~networkCacheConfig: cacheConfig=?,
54
+ ) => C.loadedQueryRef = (
55
+ ~environment,
56
+ ~variables,
57
+ ~fetchPolicy=?,
58
+ ~fetchKey=?,
59
+ ~networkCacheConfig=?,
60
+ ) =>
61
+ loadQuery(
62
+ environment,
63
+ C.query,
64
+ variables->C.convertVariables,
65
+ {
66
+ fetchKey,
67
+ fetchPolicy,
68
+ networkCacheConfig,
69
+ },
70
+ )
71
+
72
+ type rawPreloadToken<'response> = {source: Nullable.t<Observable.t<'response>>}
73
+ external tokenToRaw: C.loadedQueryRef => rawPreloadToken<C.response> = "%identity"
74
+
75
+ let queryRefToObservable = token => {
76
+ let raw = token->tokenToRaw
77
+ raw.source->Nullable.toOption
78
+ }
79
+
80
+ let queryRefToPromise = token => {
81
+ Promise.make((resolve, _) => {
82
+ switch token->queryRefToObservable {
83
+ | None => resolve(Error())
84
+ | Some(o) =>
85
+ open Observable
86
+ let _: subscription = o->subscribe(makeObserver(~complete=() => resolve(Ok())))
87
+ }
88
+ })
89
+ }
90
+ }
91
+
92
+ @module("react-relay")
93
+ external useSubscribeToInvalidationState: (array<dataId>, unit => unit) => Disposable.t =
94
+ "useSubscribeToInvalidationState"
@@ -0,0 +1,23 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ let RelayRuntime = require("relay-runtime");
5
+ let Experimental = require("relay-runtime/experimental");
6
+ let ResolverFragments = require("relay-runtime/lib/store/ResolverFragments");
7
+
8
+ function read(node, convertFragment, fRef) {
9
+ return convertFragment(ResolverFragments.readFragment(fRef, node));
10
+ }
11
+
12
+ function readInlineData_(node, convertFragment, fRef) {
13
+ return convertFragment(RelayRuntime.readInlineData(fRef, node));
14
+ }
15
+
16
+ function waitForFragmentData(environment, node, convertFragment, fRef) {
17
+ return Experimental.waitForFragmentData(environment, node, fRef).then(res => Promise.resolve(convertFragment(res)));
18
+ }
19
+
20
+ exports.read = read;
21
+ exports.readInlineData_ = readInlineData_;
22
+ exports.waitForFragmentData = waitForFragmentData;
23
+ /* relay-runtime Not a pure module */
@@ -0,0 +1,29 @@
1
+ /* React-free Fragment runtime: read, readInlineData, waitForFragmentData */
2
+
3
+ open RescriptRelay
4
+
5
+ type fragmentNode<'node> = RescriptRelay.fragmentNode<'node>
6
+
7
+ @module("relay-runtime/lib/store/ResolverFragments")
8
+ external readFragment_: (fragmentNode<'node>, 'fragmentRef) => 'fragment = "readFragment"
9
+
10
+ @module("relay-runtime")
11
+ external readInlineData: (fragmentNode<'node>, 'fragmentRef) => 'fragment = "readInlineData"
12
+
13
+ @module("relay-runtime/experimental")
14
+ external waitForFragmentData_: (
15
+ Environment.t,
16
+ fragmentNode<'node>,
17
+ 'fragmentRef,
18
+ ) => promise<'fragment> = "waitForFragmentData"
19
+
20
+ let read = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) =>
21
+ fRef->readFragment_(node)->convertFragment
22
+
23
+ let readInlineData_ = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) =>
24
+ fRef->readInlineData(node)->convertFragment
25
+
26
+ let waitForFragmentData = (~environment, ~node, ~convertFragment: 'fragment => 'fragment, ~fRef) =>
27
+ waitForFragmentData_(environment, node, fRef)->Promise.then(res =>
28
+ res->convertFragment->Promise.resolve
29
+ )
@@ -33,15 +33,15 @@ function internal_removeUndefinedAndConvertNullsRaw(record) {
33
33
  let value = param[1];
34
34
  let key = param[0];
35
35
  let match = Primitive_object.equal(value, Primitive_option.some(undefined));
36
- if (value !== undefined) {
36
+ if (match) {
37
37
  return [
38
38
  key,
39
- Primitive_option.valFromOption(value)
39
+ null
40
40
  ];
41
- } else if (match) {
41
+ } else if (value !== undefined) {
42
42
  return [
43
43
  key,
44
- null
44
+ Primitive_option.valFromOption(value)
45
45
  ];
46
46
  } else {
47
47
  return;
@@ -20,8 +20,8 @@ let internal_cleanObjectFromUndefinedRaw = record =>
20
20
  let internal_removeUndefinedAndConvertNullsRaw = record =>
21
21
  internal_keepMapFieldsRaw(record, ((key, value)) => {
22
22
  switch (value, value == Some(None)) {
23
- | (Some(value), _) => Some((key, Nullable.make(value)))
24
23
  | (_, true) => Some((key, Nullable.null))
24
+ | (Some(value), _) => Some((key, Nullable.make(value)))
25
25
  | (None, _) => None
26
26
  }
27
27
  })
@@ -0,0 +1,40 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ let Stdlib_Option = require("@rescript/runtime/lib/js/Stdlib_Option.js");
5
+ let RelayRuntime = require("relay-runtime");
6
+ let Primitive_option = require("@rescript/runtime/lib/js/Primitive_option.js");
7
+
8
+ function commitMutation(convertVariables, node, convertResponse, convertWrapRawResponse) {
9
+ return (environment, variables, optimisticUpdater, optimisticResponse, updater, onCompleted, onError, uploadables) => {
10
+ let tmp = {
11
+ mutation: node,
12
+ variables: convertVariables(variables)
13
+ };
14
+ let tmp$1 = onCompleted !== undefined ? (res, err) => onCompleted(convertResponse(res), err) : undefined;
15
+ if (tmp$1 !== undefined) {
16
+ tmp.onCompleted = Primitive_option.valFromOption(tmp$1);
17
+ }
18
+ if (onError !== undefined) {
19
+ tmp.onError = Primitive_option.valFromOption(onError);
20
+ }
21
+ let tmp$2 = Stdlib_Option.map(optimisticResponse, convertWrapRawResponse);
22
+ if (tmp$2 !== undefined) {
23
+ tmp.optimisticResponse = Primitive_option.valFromOption(tmp$2);
24
+ }
25
+ if (optimisticUpdater !== undefined) {
26
+ tmp.optimisticUpdater = Primitive_option.valFromOption(optimisticUpdater);
27
+ }
28
+ let tmp$3 = Stdlib_Option.map(updater, u => ((store, response) => u(store, convertResponse(response))));
29
+ if (tmp$3 !== undefined) {
30
+ tmp.updater = Primitive_option.valFromOption(tmp$3);
31
+ }
32
+ if (uploadables !== undefined) {
33
+ tmp.uploadables = Primitive_option.valFromOption(uploadables);
34
+ }
35
+ return RelayRuntime.commitMutation(environment, tmp);
36
+ };
37
+ }
38
+
39
+ exports.commitMutation = commitMutation;
40
+ /* relay-runtime Not a pure module */
@@ -0,0 +1,56 @@
1
+ /* React-free Mutation runtime: commitMutation only */
2
+
3
+ type mutationNode<'node> = RescriptRelay.mutationNode<'node>
4
+
5
+ @obj
6
+ external makeConfig: (
7
+ ~mutation: mutationNode<'node>,
8
+ ~variables: 'variables,
9
+ ~onCompleted: ('response, option<JSON.t>) => unit=?,
10
+ ~onError: JsExn.t => unit=?,
11
+ ~optimisticResponse: 'rawResponse=?,
12
+ ~optimisticUpdater: RescriptRelay.RecordSourceSelectorProxy.t => unit=?,
13
+ ~updater: (RescriptRelay.RecordSourceSelectorProxy.t, 'response) => unit=?,
14
+ ~uploadables: RescriptRelay.uploadables=?,
15
+ unit,
16
+ ) => 'config = ""
17
+
18
+ @module("relay-runtime")
19
+ external commitMutation: (RescriptRelay.Environment.t, 'config) => RescriptRelay.Disposable.t =
20
+ "commitMutation"
21
+
22
+ let commitMutation = (
23
+ ~convertVariables: 'variables => 'variables,
24
+ ~node: 'm,
25
+ ~convertResponse: 'response => 'response,
26
+ ~convertWrapRawResponse: 'rawResponse => 'rawResponse,
27
+ ) =>
28
+ (
29
+ ~environment: RescriptRelay.Environment.t,
30
+ ~variables: 'variables,
31
+ ~optimisticUpdater=?,
32
+ ~optimisticResponse: option<'rawResponse>=?,
33
+ ~updater: option<(RescriptRelay.RecordSourceSelectorProxy.t, 'response) => unit>=?,
34
+ ~onCompleted: option<('response, option<JSON.t>) => unit>=?,
35
+ ~onError: option<JsExn.t => unit>=?,
36
+ ~uploadables: option<RescriptRelay.uploadables>=?,
37
+ ) =>
38
+ commitMutation(
39
+ environment,
40
+ makeConfig(
41
+ ~mutation=node,
42
+ ~variables=variables->convertVariables,
43
+ ~onCompleted=?switch onCompleted {
44
+ | Some(f) => Some((res, err) => f(res->convertResponse, err))
45
+ | None => None
46
+ },
47
+ ~onError?,
48
+ ~optimisticResponse=?optimisticResponse->Option.map(convertWrapRawResponse),
49
+ ~optimisticUpdater?,
50
+ ~updater=?updater->Option.map(u =>
51
+ (store, response) => u(store, response->convertResponse)
52
+ ),
53
+ ~uploadables?,
54
+ (),
55
+ ),
56
+ )
@@ -0,0 +1,45 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+ 'use strict';
3
+
4
+ let RelayRuntime = require("relay-runtime");
5
+
6
+ function fetch(node, convertResponse, convertVariables) {
7
+ return (environment, variables, onResult, networkCacheConfig, fetchPolicy) => {
8
+ RelayRuntime.fetchQuery(environment, node, convertVariables(variables), {
9
+ networkCacheConfig: networkCacheConfig,
10
+ fetchPolicy: fetchPolicy
11
+ }).subscribe({
12
+ next: res => onResult({
13
+ TAG: "Ok",
14
+ _0: convertResponse(res)
15
+ }),
16
+ error: err => onResult({
17
+ TAG: "Error",
18
+ _0: err
19
+ })
20
+ });
21
+ };
22
+ }
23
+
24
+ function fetchPromised(node, convertResponse, convertVariables) {
25
+ return (environment, variables, networkCacheConfig, fetchPolicy) => RelayRuntime.fetchQuery(environment, node, convertVariables(variables), {
26
+ networkCacheConfig: networkCacheConfig,
27
+ fetchPolicy: fetchPolicy
28
+ }).toPromise().then(res => Promise.resolve(convertResponse(res)));
29
+ }
30
+
31
+ function retain(node, convertVariables) {
32
+ return (environment, variables) => environment.retain(RelayRuntime.createOperationDescriptor(node, convertVariables(variables)));
33
+ }
34
+
35
+ function commitLocalPayload(node, convertVariables, convertWrapRawResponse) {
36
+ return (environment, variables, payload) => {
37
+ environment.commitPayload(RelayRuntime.createOperationDescriptor(node, convertVariables(variables)), convertWrapRawResponse(payload));
38
+ };
39
+ }
40
+
41
+ exports.fetch = fetch;
42
+ exports.fetchPromised = fetchPromised;
43
+ exports.retain = retain;
44
+ exports.commitLocalPayload = commitLocalPayload;
45
+ /* relay-runtime Not a pure module */
@@ -0,0 +1,108 @@
1
+ /* React-free Query runtime: fetch, fetchPromised, retain, commitLocalPayload */
2
+
3
+ type subscription
4
+ type observable<'a>
5
+ type operationDescriptor
6
+
7
+ type queryNode<'node> = RescriptRelay.queryNode<'node>
8
+
9
+ @module("relay-runtime")
10
+ external fetchQuery: (
11
+ RescriptRelay.Environment.t,
12
+ queryNode<'node>,
13
+ 'variables,
14
+ option<RescriptRelay.fetchQueryOptions>,
15
+ ) => observable<'response> = "fetchQuery"
16
+
17
+ @module("relay-runtime")
18
+ external createOperationDescriptor: (queryNode<'node>, 'variables) => operationDescriptor =
19
+ "createOperationDescriptor"
20
+
21
+ /* moved type decls above */
22
+
23
+ @obj
24
+ external makeObserver: (
25
+ ~next: 'a => unit=?,
26
+ ~error: JsExn.t => unit=?,
27
+ ~complete: unit => unit=?,
28
+ ) => 'obs = ""
29
+
30
+ @send
31
+ external subscribe: (observable<'a>, 'obs) => subscription = "subscribe"
32
+
33
+ @send
34
+ external toPromise: observable<'a> => promise<'a> = "toPromise"
35
+
36
+ external ignoreSubscription: subscription => unit = "%ignore"
37
+
38
+ let fetch = (
39
+ ~node,
40
+ ~convertResponse: 'response => 'response,
41
+ ~convertVariables: 'variables => 'variables,
42
+ ) => {
43
+ (
44
+ ~environment: RescriptRelay.Environment.t,
45
+ ~variables: 'variables,
46
+ ~onResult,
47
+ ~networkCacheConfig=?,
48
+ ~fetchPolicy=?,
49
+ ) => {
50
+ fetchQuery(
51
+ environment,
52
+ node,
53
+ variables->convertVariables,
54
+ Some({?networkCacheConfig, ?fetchPolicy}),
55
+ )
56
+ ->subscribe(
57
+ makeObserver(
58
+ ~next=res => onResult(Ok(res->convertResponse)),
59
+ ~error=err => onResult(Error(err)),
60
+ ),
61
+ )
62
+ ->ignoreSubscription
63
+ }
64
+ }
65
+
66
+ let fetchPromised = (
67
+ ~node,
68
+ ~convertResponse: 'response => 'response,
69
+ ~convertVariables: 'variables => 'variables,
70
+ ) => {
71
+ (
72
+ ~environment: RescriptRelay.Environment.t,
73
+ ~variables: 'variables,
74
+ ~networkCacheConfig=?,
75
+ ~fetchPolicy=?,
76
+ ) =>
77
+ fetchQuery(
78
+ environment,
79
+ node,
80
+ variables->convertVariables,
81
+ Some({?networkCacheConfig, ?fetchPolicy}),
82
+ )
83
+ ->toPromise
84
+ ->Promise.then(res => res->convertResponse->Promise.resolve)
85
+ }
86
+
87
+ @send
88
+ external retain_: (RescriptRelay.Environment.t, operationDescriptor) => RescriptRelay.Disposable.t =
89
+ "retain"
90
+ @send
91
+ external commitPayload: (RescriptRelay.Environment.t, operationDescriptor, 'payload) => unit =
92
+ "commitPayload"
93
+
94
+ let retain = (~node, ~convertVariables: 'variables => 'variables) => {
95
+ (~environment: RescriptRelay.Environment.t, ~variables: 'variables) =>
96
+ environment->retain_(createOperationDescriptor(node, variables->convertVariables))
97
+ }
98
+
99
+ let commitLocalPayload = (
100
+ ~node,
101
+ ~convertVariables: 'variables => 'variables,
102
+ ~convertWrapRawResponse: 'rawResponse => 'rawResponse,
103
+ ) =>
104
+ (~environment: RescriptRelay.Environment.t, ~variables: 'variables, ~payload: 'rawResponse) =>
105
+ environment->commitPayload(
106
+ createOperationDescriptor(node, variables->convertVariables),
107
+ payload->convertWrapRawResponse,
108
+ )