rescript-relay 3.0.0-rc.8 → 3.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rescript-relay",
3
- "version": "3.0.0-rc.8",
3
+ "version": "3.0.0",
4
4
  "main": "src/RescriptRelay.res",
5
5
  "license": "MIT",
6
6
  "author": "Gabriel Nordeborn",
@@ -35,8 +35,8 @@
35
35
  "build": "rescript",
36
36
  "build:test": "./build-compiler-dev.sh && ./rescript-relay-compiler",
37
37
  "postinstall": "node postinstall.js",
38
- "test": "jest",
39
- "test:ci": "jest --ci --runInBand"
38
+ "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest",
39
+ "test:ci": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --ci --runInBand"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@glennsl/rescript-fetch": "^0.2.0",
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
@@ -117,7 +117,76 @@ var Disposable = {};
117
117
 
118
118
  var Observable = {};
119
119
 
120
- var Network = {};
120
+ var preloadResources = (function preloadResources(operation, variables, response) {
121
+ let metadata = operation.metadata;
122
+ if (metadata == null) return;
123
+ let codesplits = metadata.codesplits;
124
+ if (codesplits == null) return;
125
+ let data = response.data;
126
+
127
+ function pathExists(obj, path) {
128
+ let current = obj;
129
+
130
+ for (let i = 0; i < path.length; i++) {
131
+ let segment = path[i];
132
+
133
+ if (Array.isArray(current)) {
134
+ return current.some((item) => pathExists(item, path.slice(i)));
135
+ } else if (current != null && current.hasOwnProperty(segment)) {
136
+ current = current[segment];
137
+ } else if (current != null && (segment.startsWith("$$u$$") || segment.startsWith("$$i$$"))) {
138
+ let isInterface = segment.startsWith("$$i$$");
139
+ let expectedTypename = segment.slice(5);
140
+ if (
141
+ (
142
+ !isInterface &&
143
+ current.hasOwnProperty("__typename") &&
144
+ current.__typename === expectedTypename) ||
145
+ (
146
+ isInterface &&
147
+ current.hasOwnProperty("__is" + expectedTypename) &&
148
+ current["__is" + expectedTypename] != null
149
+ )
150
+ ) {
151
+ if (i + 1 === path.length) {
152
+ // End
153
+ return true;
154
+ } else {
155
+ continue;
156
+ }
157
+ } else {
158
+ return false;
159
+ }
160
+ } else {
161
+ return false;
162
+ }
163
+ }
164
+
165
+ return current != null;
166
+ }
167
+
168
+ function run() {
169
+ for (let instruction of codesplits) {
170
+ let path = instruction[0];
171
+ let func = instruction[1];
172
+ if (pathExists(data, path.split("."))) {
173
+ func(variables);
174
+ }
175
+ }
176
+ }
177
+
178
+ if ("requestIdleCallback" in window) {
179
+ requestIdleCallback(run);
180
+ } else {
181
+ setTimeout(() => {
182
+ Promise.resolve().then(run);
183
+ }, 1);
184
+ }
185
+ });
186
+
187
+ var Network = {
188
+ preloadResources: preloadResources
189
+ };
121
190
 
122
191
  var RecordSource = {};
123
192
 
@@ -9,6 +9,7 @@ type mutationNode<'node>
9
9
  type subscriptionNode<'node>
10
10
 
11
11
  type fragmentRefs<'fragments>
12
+ type resolverFragmentRefs<'fragments>
12
13
  type updatableFragmentRefs<'fragments>
13
14
 
14
15
  type dataId
@@ -503,11 +504,16 @@ module Observable = {
503
504
  module Network = {
504
505
  type t
505
506
 
507
+ type codesplitsMetadata = (string, unit => unit)
508
+
509
+ type operationMetadata = {codesplits?: array<codesplitsMetadata>}
510
+
506
511
  type operation = {
507
512
  id: string,
508
513
  text: string,
509
514
  name: string,
510
515
  operationKind: string,
516
+ metadata: Js.Nullable.t<operationMetadata>,
511
517
  }
512
518
 
513
519
  type subscribeFn = (operation, Js.Json.t, cacheConfig) => Observable.t<Js.Json.t>
@@ -537,6 +543,79 @@ module Network = {
537
543
  ~observableFunction: fetchFunctionObservable,
538
544
  ~subscriptionFunction: subscribeFn=?,
539
545
  ) => t = "create"
546
+
547
+ let preloadResources: (
548
+ ~operation: operation,
549
+ ~variables: Js.Json.t,
550
+ ~response: Js.Json.t,
551
+ ) => unit = %raw(`
552
+ function preloadResources(operation, variables, response) {
553
+ let metadata = operation.metadata;
554
+ if (metadata == null) return;
555
+ let codesplits = metadata.codesplits;
556
+ if (codesplits == null) return;
557
+ let data = response.data;
558
+
559
+ function pathExists(obj, path) {
560
+ let current = obj;
561
+
562
+ for (let i = 0; i < path.length; i++) {
563
+ let segment = path[i];
564
+
565
+ if (Array.isArray(current)) {
566
+ return current.some((item) => pathExists(item, path.slice(i)));
567
+ } else if (current != null && current.hasOwnProperty(segment)) {
568
+ current = current[segment];
569
+ } else if (current != null && (segment.startsWith("$$u$$") || segment.startsWith("$$i$$"))) {
570
+ let isInterface = segment.startsWith("$$i$$");
571
+ let expectedTypename = segment.slice(5);
572
+ if (
573
+ (
574
+ !isInterface &&
575
+ current.hasOwnProperty("__typename") &&
576
+ current.__typename === expectedTypename) ||
577
+ (
578
+ isInterface &&
579
+ current.hasOwnProperty("__is" + expectedTypename) &&
580
+ current["__is" + expectedTypename] != null
581
+ )
582
+ ) {
583
+ if (i + 1 === path.length) {
584
+ // End
585
+ return true;
586
+ } else {
587
+ continue;
588
+ }
589
+ } else {
590
+ return false;
591
+ }
592
+ } else {
593
+ return false;
594
+ }
595
+ }
596
+
597
+ return current != null;
598
+ }
599
+
600
+ function run() {
601
+ for (let instruction of codesplits) {
602
+ let path = instruction[0];
603
+ let func = instruction[1];
604
+ if (pathExists(data, path.split("."))) {
605
+ func(variables);
606
+ }
607
+ }
608
+ }
609
+
610
+ if ("requestIdleCallback" in window) {
611
+ requestIdleCallback(run);
612
+ } else {
613
+ setTimeout(() => {
614
+ Promise.resolve().then(run);
615
+ }, 1);
616
+ }
617
+ }
618
+ `)
540
619
  }
541
620
 
542
621
  module RecordSource = {
@@ -30,6 +30,9 @@ type subscriptionNode<'node>
30
30
  /**This type shows all of the fragments that has been spread on this particular object.*/
31
31
  type fragmentRefs<'fragments>
32
32
 
33
+ /**This type shows the Relay resolver fragment that has been spread on this particular object.*/
34
+ type resolverFragmentRefs<'fragments>
35
+
33
36
  /**This type shows all of the updatable fragments that has been spread on this particular object.*/
34
37
  type updatableFragmentRefs<'fragments>
35
38
 
@@ -608,6 +611,10 @@ module Observable: {
608
611
 
609
612
  /**Represents the network layer.*/
610
613
  module Network: {
614
+ type codesplitsMetadata = (string, unit => unit)
615
+
616
+ type operationMetadata = {codesplits?: array<codesplitsMetadata>}
617
+
611
618
  /**The type representing an instantiated `NetworkLayer`.*/
612
619
  type t
613
620
 
@@ -617,6 +624,7 @@ module Network: {
617
624
  text: string,
618
625
  name: string,
619
626
  operationKind: string,
627
+ metadata: Js.Nullable.t<operationMetadata>,
620
628
  }
621
629
 
622
630
  /**The shape of the function Relay expects for creating a subscription.*/
@@ -653,6 +661,8 @@ module Network: {
653
661
  ~observableFunction: fetchFunctionObservable,
654
662
  ~subscriptionFunction: subscribeFn=?,
655
663
  ) => t = "create"
664
+
665
+ let preloadResources: (~operation: operation, ~variables: Js.Json.t, ~response: Js.Json.t) => unit
656
666
  }
657
667
 
658
668
  /**RecordSource is the source of records used by the store. Can be initiated with or without prior records; eg. hydrating the store with prior data.*/
@@ -5,6 +5,7 @@ var React = require("react");
5
5
  var Caml_option = require("rescript/lib/js/caml_option.js");
6
6
  var ReactRelay = require("react-relay");
7
7
  var RescriptRelay_Internal = require("./RescriptRelay_Internal.bs.js");
8
+ var ResolverFragments = require("relay-runtime/lib/store/ResolverFragments");
8
9
  var UseBlockingPaginationFragment = require("react-relay/lib/relay-hooks/legacy/useBlockingPaginationFragment").default;
9
10
 
10
11
  function useFragment(node, convertFragment, fRef) {
@@ -26,6 +27,10 @@ function readInlineData(node, convertFragment, fRef) {
26
27
  return convertFragment(ReactRelay.readInlineData(node, fRef));
27
28
  }
28
29
 
30
+ function read(node, convertFragment, fRef) {
31
+ return convertFragment(ResolverFragments.readFragment(node, fRef));
32
+ }
33
+
29
34
  function internal_makeRefetchableFnOpts(fetchPolicy, onComplete, param) {
30
35
  return {
31
36
  fetchPolicy: fetchPolicy,
@@ -110,6 +115,7 @@ function useRefetchableFragment(node, convertFragment, convertRefetchVariables,
110
115
  exports.useFragment = useFragment;
111
116
  exports.useFragmentOpt = useFragmentOpt;
112
117
  exports.readInlineData = readInlineData;
118
+ exports.read = read;
113
119
  exports.usePaginationFragment = usePaginationFragment;
114
120
  exports.useBlockingPaginationFragment = useBlockingPaginationFragment;
115
121
  exports.useRefetchableFragment = useRefetchableFragment;
@@ -52,6 +52,16 @@ let readInlineData = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) =>
52
52
  (readInlineData_(node, fRef)->convertFragment)
53
53
  }
54
54
 
55
+ @module("relay-runtime/lib/store/ResolverFragments")
56
+ external read_: (fragmentNode<'node>, 'fragmentRef) => 'fragment = "readFragment"
57
+
58
+ let read = (~node, ~convertFragment: 'fragment => 'fragment, ~fRef) => {
59
+ /** This lets you get the data for this fragment _outside \
60
+ of React's render_. Useful for letting functions with \
61
+ with fragments too, for things like logging etc.*/
62
+ (read_(node, fRef)->convertFragment)
63
+ }
64
+
55
65
  type refetchableFnOpts = {
56
66
  fetchPolicy?: fetchPolicy,
57
67
  onComplete?: Js.Nullable.t<Js.Exn.t> => unit,
@@ -18,6 +18,12 @@ let readInlineData: (
18
18
  ~fRef: 'b,
19
19
  ) => 'fragment
20
20
 
21
+ let read: (
22
+ ~node: fragmentNode<'a>,
23
+ ~convertFragment: 'fragment => 'fragment,
24
+ ~fRef: 'b,
25
+ ) => 'fragment
26
+
21
27
  type paginationLoadMoreOptions = {onComplete?: Js.Nullable.t<Js.Exn.t> => unit}
22
28
 
23
29
  type paginationLoadMoreFn = (~count: int, ~onComplete: option<Js.Exn.t> => unit=?) => Disposable.t
@@ -80,10 +80,23 @@ function wrapUnion(union) {
80
80
  return union;
81
81
  }
82
82
 
83
+ var applyCodesplitMetadata = (function applyCodesplitMetadata(node, meta) {
84
+ if (node != null && node.params != null) {
85
+ let metadata = node.params.metadata;
86
+ if (metadata == null) {
87
+ node.params.metadata = {codesplits: meta}
88
+ } else if (typeof metadata === "object") {
89
+ node.params.metadata.codesplits = meta
90
+ }
91
+ }
92
+ return node;
93
+ });
94
+
83
95
  exports.internal_useConvertedValue = internal_useConvertedValue;
84
96
  exports.internal_cleanObjectFromUndefinedRaw = internal_cleanObjectFromUndefinedRaw;
85
97
  exports.internal_removeUndefinedAndConvertNullsRaw = internal_removeUndefinedAndConvertNullsRaw;
86
98
  exports.internal_nullableToOptionalExnHandler = internal_nullableToOptionalExnHandler;
87
99
  exports.unwrapUnion = unwrapUnion;
88
100
  exports.wrapUnion = wrapUnion;
101
+ exports.applyCodesplitMetadata = applyCodesplitMetadata;
89
102
  /* react Not a pure module */
@@ -47,3 +47,25 @@ let unwrapUnion: ('a, array<string>) => 'a = %raw(`
47
47
  `)
48
48
 
49
49
  let wrapUnion = union => union
50
+
51
+ external internal_resolverFragmentRefsToFragmentRefs: RescriptRelay.resolverFragmentRefs<
52
+ 'a,
53
+ > => RescriptRelay.fragmentRefs<'a> = "%identity"
54
+
55
+ external internal_resolverFragmentRefsToFragmentRefsPlural: RescriptRelay.resolverFragmentRefs<
56
+ 'a,
57
+ > => array<RescriptRelay.fragmentRefs<'a>> = "%identity"
58
+
59
+ let applyCodesplitMetadata: ('node, array<(string, dict<Js.Json.t> => unit)>) => 'node = %raw(`
60
+ function applyCodesplitMetadata(node, meta) {
61
+ if (node != null && node.params != null) {
62
+ let metadata = node.params.metadata;
63
+ if (metadata == null) {
64
+ node.params.metadata = {codesplits: meta}
65
+ } else if (typeof metadata === "object") {
66
+ node.params.metadata.codesplits = meta
67
+ }
68
+ }
69
+ return node;
70
+ }
71
+ `)
@@ -8,3 +8,13 @@ let internal_nullableToOptionalExnHandler: option<option<'b> => 'a> => option<
8
8
 
9
9
  let unwrapUnion: ('a, array<string>) => 'a
10
10
  let wrapUnion: 'a => 'a
11
+
12
+ external internal_resolverFragmentRefsToFragmentRefs: RescriptRelay.resolverFragmentRefs<
13
+ 'a,
14
+ > => RescriptRelay.fragmentRefs<'a> = "%identity"
15
+
16
+ external internal_resolverFragmentRefsToFragmentRefsPlural: RescriptRelay.resolverFragmentRefs<
17
+ 'a,
18
+ > => array<RescriptRelay.fragmentRefs<'a>> = "%identity"
19
+
20
+ let applyCodesplitMetadata: ('node, array<(string, dict<Js.Json.t> => unit)>) => 'node
@@ -1,23 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
- 'use strict';
3
-
4
- var React = require("react");
5
-
6
- function useTransition() {
7
- var match = React.useTransition();
8
- var startTransition = match[1];
9
- return [
10
- match[0],
11
- React.useMemo((function () {
12
- return function (cb) {
13
- startTransition(cb, undefined);
14
- };
15
- }), [startTransition])
16
- ];
17
- }
18
-
19
- var SuspenseList = {};
20
-
21
- exports.useTransition = useTransition;
22
- exports.SuspenseList = SuspenseList;
23
- /* react Not a pure module */
@@ -1,21 +0,0 @@
1
- @module("react")
2
- external useDeferredValue: 'value => 'value = "useDeferredValue"
3
-
4
- @module("react")
5
- external useTransitionWithOptions: unit => (
6
- bool,
7
- (unit => unit, option<{"name": option<string>}>) => unit,
8
- ) = "useTransition"
9
-
10
- let useTransition = () => {
11
- let (isPending, startTransition) = useTransitionWithOptions()
12
- (isPending, React.useMemo1(() => cb => startTransition(cb, None), [startTransition]))
13
- }
14
-
15
- module SuspenseList = {
16
- @module("react") @react.component
17
- external make: (
18
- ~children: React.element,
19
- ~revealOrder: [#forwards | #backwards | #together]=?,
20
- ) => React.element = "SuspenseList"
21
- }
@@ -1,18 +0,0 @@
1
- @module("react")
2
- external useDeferredValue: 'value => 'value = "useDeferredValue"
3
-
4
- @module("react")
5
- external useTransitionWithOptions: unit => (
6
- bool,
7
- (unit => unit, option<{"name": option<string>}>) => unit,
8
- ) = "useTransition"
9
-
10
- let useTransition: unit => (bool, (unit => unit) => unit)
11
-
12
- module SuspenseList: {
13
- @module("react") @react.component
14
- external make: (
15
- ~children: React.element,
16
- ~revealOrder: [#forwards | #backwards | #together]=?,
17
- ) => React.element = "SuspenseList"
18
- }