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/CHANGELOG.md +9 -1
- package/cli/cli.js +8 -8
- package/package.json +3 -3
- 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 +70 -1
- package/src/RescriptRelay.res +79 -0
- package/src/RescriptRelay.resi +10 -0
- package/src/RescriptRelay_Fragment.bs.js +6 -0
- package/src/RescriptRelay_Fragment.res +10 -0
- package/src/RescriptRelay_Fragment.resi +6 -0
- package/src/RescriptRelay_Internal.bs.js +13 -0
- package/src/RescriptRelay_Internal.res +22 -0
- package/src/RescriptRelay_Internal.resi +10 -0
- package/src/ReactExperimental.bs.js +0 -23
- package/src/ReactExperimental.res +0 -21
- package/src/ReactExperimental.resi +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rescript-relay",
|
|
3
|
-
"version": "3.0.0
|
|
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
|
package/ppx-windows-latest
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/RescriptRelay.bs.js
CHANGED
|
@@ -117,7 +117,76 @@ var Disposable = {};
|
|
|
117
117
|
|
|
118
118
|
var Observable = {};
|
|
119
119
|
|
|
120
|
-
var
|
|
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
|
|
package/src/RescriptRelay.res
CHANGED
|
@@ -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 = {
|
package/src/RescriptRelay.resi
CHANGED
|
@@ -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
|
-
}
|