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.
@@ -9,6 +9,7 @@ var Belt_Array = require("rescript/lib/js/belt_Array.js");
9
9
  var Belt_Option = require("rescript/lib/js/belt_Option.js");
10
10
  var Caml_option = require("rescript/lib/js/caml_option.js");
11
11
  var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
12
+ var ReactExperimental = require("../ReactExperimental.bs.js");
12
13
  var RescriptReactRouter = require("@rescript/react/src/RescriptReactRouter.bs.js");
13
14
 
14
15
  function matchesUrl(t, url) {
@@ -242,8 +243,8 @@ function RescriptRelayRouter$RouteRenderer(Props) {
242
243
  });
243
244
  var initialized = match[0];
244
245
  var router = React.useContext(context);
245
- var match$1 = React.unstable_useTransition();
246
- var startTransition = match$1[0];
246
+ var match$1 = ReactExperimental.useTransition(undefined);
247
+ var startTransition = match$1[1];
247
248
  var match$2 = React.useState(function () {
248
249
  return Curry._1(router.get, undefined);
249
250
  });
@@ -281,7 +282,7 @@ function RescriptRelayRouter$RouteRenderer(Props) {
281
282
  var match$4 = routeEntry.route;
282
283
  var renderedContent = initialized && match$4 !== undefined ? Caml_option.some(Curry._1(match$4.render, routeEntry.url)) : undefined;
283
284
  if (initialized) {
284
- return React.createElement(React.Fragment, undefined, renderPending !== undefined ? Curry._1(renderPending, match$1[1]) : null, React.createElement(React.Suspense, {
285
+ return React.createElement(React.Fragment, undefined, renderPending !== undefined ? Curry._1(renderPending, match$1[0]) : null, React.createElement(React.Suspense, {
285
286
  children: renderedContent !== undefined ? Caml_option.valFromOption(renderedContent) : (
286
287
  renderNotFound !== undefined ? Curry._1(renderNotFound, routeEntry.url) : null
287
288
  ),
@@ -315,10 +316,12 @@ function RescriptRelayRouter$Link(Props) {
315
316
  var className = Props.className;
316
317
  var classNameDynamic = Props.classNameDynamic;
317
318
  var browserTarget = Props.target;
319
+ var tabIndex = Props.tabIndex;
318
320
  var mode = Props.mode;
319
321
  var render = Props.render;
320
322
  var preloadOnHover = Props.preloadOnHover;
321
323
  var children = Props.children;
324
+ var onClick = Props.onClick;
322
325
  var router = React.useContext(context);
323
326
  var url = RescriptReactRouter.useUrl(undefined, undefined);
324
327
  var changeRoute = React.useCallback((function (e) {
@@ -369,7 +372,13 @@ function RescriptRelayRouter$Link(Props) {
369
372
  target: browserTarget !== undefined ? (
370
373
  browserTarget === "blank" ? "_blank" : "_self"
371
374
  ) : "",
372
- onClick: changeRoute,
375
+ onClick: (function (e) {
376
+ Curry._1(changeRoute, e);
377
+ if (onClick !== undefined) {
378
+ return Curry._1(onClick, undefined);
379
+ }
380
+
381
+ }),
373
382
  onMouseDown: (function (param) {
374
383
  return Curry._1(preload, undefined);
375
384
  }),
@@ -386,6 +395,9 @@ function RescriptRelayRouter$Link(Props) {
386
395
  if (id !== undefined) {
387
396
  tmp.id = Caml_option.valFromOption(id);
388
397
  }
398
+ if (tabIndex !== undefined) {
399
+ tmp.tabIndex = Caml_option.valFromOption(tabIndex);
400
+ }
389
401
  if (title !== undefined) {
390
402
  tmp.title = Caml_option.valFromOption(title);
391
403
  }
@@ -233,7 +233,7 @@ module RouteRenderer = {
233
233
  let (initialized, setInitialized) = React.useState(() => false)
234
234
  let router = use()
235
235
 
236
- let (startTransition, isPending) = ReactExperimental.unstable_useTransition()
236
+ let (isPending, startTransition) = ReactExperimental.useTransition()
237
237
 
238
238
  let (routeEntry, setRouteEntry) = React.useState(() => router.get())
239
239
 
@@ -306,10 +306,12 @@ module Link = {
306
306
  ~className=?,
307
307
  ~classNameDynamic=?,
308
308
  ~target as browserTarget=?,
309
+ ~tabIndex=?,
309
310
  ~mode=?,
310
311
  ~render=?,
311
312
  ~preloadOnHover=?,
312
313
  ~children,
314
+ ~onClick=?,
313
315
  (),
314
316
  ) => {
315
317
  let router = use()
@@ -350,12 +352,19 @@ module Link = {
350
352
  }}
351
353
  ?title
352
354
  ?id
355
+ ?tabIndex
353
356
  className={className->Belt.Option.getWithDefault("") ++
354
357
  switch classNameDynamic {
355
358
  | Some(f) => " " ++ f(url, to_->Url.make)
356
359
  | None => ""
357
360
  }}
358
- onClick=changeRoute
361
+ onClick={e => {
362
+ changeRoute(e)
363
+ switch onClick {
364
+ | None => ()
365
+ | Some(onClick) => onClick()
366
+ }
367
+ }}
359
368
  onMouseDown={_ => preload()}
360
369
  onTouchStart={_ => preload()}
361
370
  onMouseEnter={_ =>
@@ -56,6 +56,7 @@ module Link: {
56
56
  ~className: string=?,
57
57
  ~classNameDynamic: (RescriptReactRouter.url, RescriptReactRouter.url) => string=?,
58
58
  ~target: [#self | #blank]=?,
59
+ ~tabIndex: int=?,
59
60
  ~mode: [#push | #replace]=?,
60
61
  ~render: (
61
62
  ~preload: unit => unit,
@@ -65,6 +66,7 @@ module Link: {
65
66
  ) => React.element=?,
66
67
  ~preloadOnHover: bool=?,
67
68
  ~children: React.element,
69
+ ~onClick: unit => unit=?,
68
70
  unit,
69
71
  ) => React.element
70
72
  }
package/src/utils.js CHANGED
@@ -10,6 +10,19 @@ function makeNewPath(currentPath, newKeys) {
10
10
  return [].concat(currentPath, newKeys);
11
11
  }
12
12
 
13
+ function getTypename(v) {
14
+ if (v != null && typeof v === "object") {
15
+ if (v.__typename) {
16
+ return v.__typename;
17
+ }
18
+
19
+ // `v.VAL` relies on internal implementation details in ReScript.
20
+ if (v.VAL != null && typeof v.VAL === "object") {
21
+ return v.VAL.__typename;
22
+ }
23
+ }
24
+ }
25
+
13
26
  /**
14
27
  * Runs on each object in the tree and follows the provided instructions
15
28
  * to apply transforms etc.
@@ -24,6 +37,10 @@ function traverse(
24
37
  instructionPaths,
25
38
  addFragmentOnRoot
26
39
  ) {
40
+ // We lazily set up a new object for each "level", as we don't want to mutate
41
+ // what comes back from the Relay store, and nor do we want to create new
42
+ // objects unless we need to. And we only need to when we need to change
43
+ // something.
27
44
  var newObj;
28
45
 
29
46
  if (addFragmentOnRoot) {
@@ -32,6 +49,8 @@ function traverse(
32
49
  }
33
50
 
34
51
  for (var key in currentObj) {
52
+ if (key === "VAL" || key === "NAME") continue;
53
+
35
54
  var isUnion = false;
36
55
  var originalValue = currentObj[key];
37
56
 
@@ -39,157 +58,73 @@ function traverse(
39
58
  var thisPath = makeNewPath(currentPath, [key]);
40
59
  var path = getPathName(thisPath);
41
60
 
42
- var instructions = instructionMap[path];
43
-
44
- var hasDeeperInstructions =
45
- instructionPaths.filter(function (p) {
46
- return p.indexOf(path) === 0 && p.length > path.length;
47
- }).length > 0;
61
+ var instructions = instructionMap[path] || {};
48
62
 
49
- if (instructions) {
50
- if (currentObj[key] == null) {
51
- if (instructions["n"] === "") {
52
- newObj = getNewObj(newObj, currentObj);
53
- newObj[key] = nullableValue;
54
- }
55
- } else {
56
- var shouldConvertRootObj =
57
- typeof instructions["r"] === "string" &&
58
- fullInstructionMap[instructions["r"]];
63
+ if (currentObj[key] == null) {
64
+ newObj = getNewObj(newObj, currentObj);
65
+ newObj[key] = nullableValue;
66
+ continue;
67
+ }
59
68
 
60
- var shouldAddFragmentFn = instructions["f"] === "";
69
+ var shouldConvertRootObj =
70
+ typeof instructions["r"] === "string" &&
71
+ fullInstructionMap[instructions["r"]];
61
72
 
62
- var shouldConvertEnum =
63
- typeof instructions["e"] === "string" &&
64
- !!converters[instructions["e"]];
73
+ var shouldAddFragmentFn = instructions["f"] === "";
65
74
 
66
- var shouldConvertCustomField =
67
- typeof instructions["c"] === "string" &&
68
- !!converters[instructions["c"]];
75
+ var shouldConvertEnum =
76
+ typeof instructions["e"] === "string" && !!converters[instructions["e"]];
69
77
 
70
- var shouldConvertUnion =
71
- typeof instructions["u"] === "string" &&
72
- !!converters[instructions["u"]];
78
+ var shouldConvertCustomField =
79
+ typeof instructions["c"] === "string" && !!converters[instructions["c"]];
73
80
 
74
- var isTopLevelNodeField = typeof instructions["tnf"] === "string";
81
+ var shouldConvertUnion =
82
+ typeof instructions["u"] === "string" && !!converters[instructions["u"]];
75
83
 
76
- /**
77
- * Handle arrays
78
- */
79
- if (Array.isArray(currentObj[key])) {
80
- newObj = getNewObj(newObj, currentObj);
81
- newObj[key] = currentObj[key].map(function (v) {
82
- if (v == null) {
83
- return nullableValue;
84
- }
84
+ var isTopLevelNodeField = typeof instructions["tnf"] === "string";
85
85
 
86
- if (shouldConvertRootObj) {
87
- return traverser(
88
- v,
89
- fullInstructionMap,
90
- converters,
91
- nullableValue,
92
- instructions["r"]
93
- );
94
- }
86
+ /**
87
+ * Handle arrays
88
+ */
89
+ if (Array.isArray(currentObj[key])) {
90
+ newObj = getNewObj(newObj, currentObj);
91
+ newObj[key] = currentObj[key].map(function (v) {
92
+ if (v == null) {
93
+ return nullableValue;
94
+ }
95
95
 
96
- if (shouldConvertEnum) {
97
- return converters[instructions["e"]](v);
98
- }
96
+ if (shouldConvertRootObj) {
97
+ return traverser(
98
+ v,
99
+ fullInstructionMap,
100
+ converters,
101
+ nullableValue,
102
+ instructions["r"]
103
+ );
104
+ }
99
105
 
100
- if (shouldConvertCustomField) {
101
- return converters[instructions["c"]](v);
102
- }
106
+ if (shouldConvertEnum) {
107
+ return converters[instructions["e"]](v);
108
+ }
103
109
 
104
- if (
105
- shouldConvertUnion &&
106
- typeof v === "object" &&
107
- typeof v.__typename === "string"
108
- ) {
109
- isUnion = true;
110
-
111
- var newPath = makeNewPath(currentPath, [
112
- key,
113
- v.__typename.toLowerCase(),
114
- ]);
115
-
116
- var unionRootHasFragment =
117
- (instructionMap[getPathName(newPath)] || {}).f === "";
118
-
119
- var traversedValue = traverse(
120
- fullInstructionMap,
121
- newPath,
122
- v,
123
- instructionMap,
124
- converters,
125
- nullableValue,
126
- instructionPaths,
127
- unionRootHasFragment
128
- );
129
-
130
- return converters[instructions["u"]](traversedValue);
131
- }
110
+ if (shouldConvertCustomField) {
111
+ return converters[instructions["c"]](v);
112
+ }
132
113
 
133
- if (shouldAddFragmentFn && typeof v === "object") {
134
- var objWithFragmentFn = Object.assign({}, v);
135
- objWithFragmentFn.fragmentRefs = Object.assign(
136
- {},
137
- objWithFragmentFn
138
- );
139
- return objWithFragmentFn;
140
- }
114
+ if (shouldConvertUnion && v != null && typeof v === "object") {
115
+ var typename = getTypename(v);
141
116
 
142
- return v;
143
- });
144
- } else {
145
- /**
146
- * Handle normal values.
147
- */
148
- var v = currentObj[key];
149
-
150
- if (shouldConvertRootObj) {
151
- newObj = getNewObj(newObj, currentObj);
152
- newObj[key] = traverser(
153
- v,
154
- fullInstructionMap,
155
- converters,
156
- nullableValue,
157
- instructions["r"]
158
- );
159
- }
117
+ if (typename != null) {
118
+ isUnion = true;
119
+ var unionObj = v;
160
120
 
161
- if (isTopLevelNodeField) {
162
- if (
163
- !v ||
164
- !v.hasOwnProperty("__typename") ||
165
- v.__typename !== instructions["tnf"]
166
- ) {
167
- newObj = getNewObj(newObj, currentObj);
168
- newObj[key] = nullableValue;
121
+ // Means we're wrapping, and this will be a ReScript value.
122
+ if (nullableValue === null) {
123
+ // Convert it back to a flat JS value
124
+ unionObj = converters[instructions["u"]](v);
169
125
  }
170
- }
171
126
 
172
- if (shouldConvertEnum) {
173
- newObj = getNewObj(newObj, currentObj);
174
- newObj[key] = converters[instructions["e"]](v);
175
- }
176
-
177
- if (shouldConvertCustomField) {
178
- newObj = getNewObj(newObj, currentObj);
179
- newObj[key] = converters[instructions["c"]](v);
180
- }
181
-
182
- if (
183
- shouldConvertUnion &&
184
- typeof v === "object" &&
185
- typeof v.__typename === "string"
186
- ) {
187
- isUnion = true;
188
-
189
- var newPath = makeNewPath(currentPath, [
190
- key,
191
- v.__typename.toLowerCase(),
192
- ]);
127
+ var newPath = makeNewPath(currentPath, [key, typename]);
193
128
 
194
129
  var unionRootHasFragment =
195
130
  (instructionMap[getPathName(newPath)] || {}).f === "";
@@ -197,7 +132,7 @@ function traverse(
197
132
  var traversedValue = traverse(
198
133
  fullInstructionMap,
199
134
  newPath,
200
- v,
135
+ unionObj,
201
136
  instructionMap,
202
137
  converters,
203
138
  nullableValue,
@@ -205,27 +140,113 @@ function traverse(
205
140
  unionRootHasFragment
206
141
  );
207
142
 
208
- newObj = getNewObj(newObj, currentObj);
209
- newObj[key] = converters[instructions["u"]](traversedValue);
143
+ // Undefined means we're going from JS to ReScript, in which case we
144
+ // need to run the conversion here rather than earlier.
145
+ return nullableValue === undefined
146
+ ? converters[instructions["u"]](traversedValue)
147
+ : traversedValue;
210
148
  }
149
+ }
211
150
 
212
- if (shouldAddFragmentFn && typeof v === "object") {
213
- newObj = getNewObj(newObj, currentObj);
151
+ if (shouldAddFragmentFn && typeof v === "object") {
152
+ var objWithFragmentFn = Object.assign({}, v);
153
+ objWithFragmentFn.fragmentRefs = Object.assign({}, objWithFragmentFn);
154
+ return objWithFragmentFn;
155
+ }
214
156
 
215
- var objWithFragmentFn = Object.assign({}, v);
157
+ return v;
158
+ });
159
+ } else {
160
+ /**
161
+ * Handle normal values.
162
+ */
163
+ var v = currentObj[key];
216
164
 
217
- objWithFragmentFn.fragmentRefs = Object.assign(
218
- {},
219
- objWithFragmentFn
220
- );
165
+ if (shouldConvertRootObj) {
166
+ newObj = getNewObj(newObj, currentObj);
167
+ newObj[key] = traverser(
168
+ v,
169
+ fullInstructionMap,
170
+ converters,
171
+ nullableValue,
172
+ instructions["r"]
173
+ );
174
+ }
175
+
176
+ if (isTopLevelNodeField) {
177
+ // If this is a top level node field we should try and convert, ensure
178
+ // it conforms to the desired shape (has the correct typename). If not,
179
+ // null it and return right away.
180
+ if (
181
+ v == null ||
182
+ !v.hasOwnProperty("__typename") ||
183
+ v.__typename !== instructions["tnf"]
184
+ ) {
185
+ newObj = getNewObj(newObj, currentObj);
186
+ newObj[key] = nullableValue;
187
+ return newObj;
188
+ }
189
+ }
190
+
191
+ if (shouldConvertEnum) {
192
+ newObj = getNewObj(newObj, currentObj);
193
+ newObj[key] = converters[instructions["e"]](v);
194
+ }
221
195
 
222
- newObj[key] = objWithFragmentFn;
196
+ if (shouldConvertCustomField) {
197
+ newObj = getNewObj(newObj, currentObj);
198
+ newObj[key] = converters[instructions["c"]](v);
199
+ }
200
+
201
+ if (shouldConvertUnion && v != null && typeof v === "object") {
202
+ var typename = getTypename(v);
203
+
204
+ if (typename != null) {
205
+ isUnion = true;
206
+ var unionObj = v;
207
+
208
+ // Means we're wrapping, and this will be a ReScript value.
209
+ if (nullableValue === null) {
210
+ // Convert it back to a flat JS value
211
+ unionObj = converters[instructions["u"]](v);
223
212
  }
213
+
214
+ var newPath = makeNewPath(currentPath, [key, typename]);
215
+
216
+ var unionRootHasFragment =
217
+ (instructionMap[getPathName(newPath)] || {}).f === "";
218
+
219
+ var traversedValue = traverse(
220
+ fullInstructionMap,
221
+ newPath,
222
+ unionObj,
223
+ instructionMap,
224
+ converters,
225
+ nullableValue,
226
+ instructionPaths,
227
+ unionRootHasFragment
228
+ );
229
+
230
+ newObj = getNewObj(newObj, currentObj);
231
+
232
+ newObj[key] =
233
+ // Undefined means we're going from JS to ReScript, in which case we
234
+ // need to run the conversion here rather than earlier.
235
+ nullableValue === undefined
236
+ ? converters[instructions["u"]](traversedValue)
237
+ : traversedValue;
224
238
  }
225
239
  }
240
+
241
+ if (shouldAddFragmentFn && typeof v === "object") {
242
+ newObj = getNewObj(newObj, currentObj);
243
+ var objWithFragmentFn = Object.assign({}, v);
244
+ objWithFragmentFn.fragmentRefs = Object.assign({}, objWithFragmentFn);
245
+ newObj[key] = objWithFragmentFn;
246
+ }
226
247
  }
227
248
 
228
- if (hasDeeperInstructions && originalValue != null && !isUnion) {
249
+ if (originalValue != null && !isUnion) {
229
250
  var nextObj = (newObj && newObj[key]) || currentObj[key];
230
251
 
231
252
  if (typeof nextObj === "object" && !Array.isArray(originalValue)) {
@@ -246,17 +267,21 @@ function traverse(
246
267
  } else if (Array.isArray(originalValue)) {
247
268
  newObj = getNewObj(newObj, currentObj);
248
269
  newObj[key] = nextObj.map(function (o) {
249
- return typeof o === "object" && o != null
250
- ? traverse(
251
- fullInstructionMap,
252
- thisPath,
253
- o,
254
- instructionMap,
255
- converters,
256
- nullableValue,
257
- instructionPaths
258
- )
259
- : o;
270
+ if (typeof o === "object" && o != null) {
271
+ return traverse(
272
+ fullInstructionMap,
273
+ thisPath,
274
+ o,
275
+ instructionMap,
276
+ converters,
277
+ nullableValue,
278
+ instructionPaths
279
+ );
280
+ } else if (o == null) {
281
+ return nullableValue;
282
+ } else {
283
+ return o;
284
+ }
260
285
  });
261
286
  }
262
287
  }
@@ -276,7 +301,7 @@ function traverse(
276
301
  */
277
302
  function traverser(
278
303
  root,
279
- _instructionMaps,
304
+ instructionMaps_,
280
305
  theConverters,
281
306
  nullableValue,
282
307
  rootObjectKey
@@ -285,22 +310,12 @@ function traverser(
285
310
  return nullableValue;
286
311
  }
287
312
 
288
- var instructionMaps = _instructionMaps || {};
289
- var instructionMap = instructionMaps[rootObjectKey || "__root"];
290
-
291
- // No instructions
292
- if (!instructionMap) {
293
- return root;
294
- }
313
+ var instructionMaps = instructionMaps_ || {};
314
+ var instructionMap = instructionMaps[rootObjectKey || "__root"] || {};
295
315
 
296
316
  var converters = theConverters == null ? {} : theConverters;
297
317
  var instructionPaths = Object.keys(instructionMap);
298
318
 
299
- // Nothing to convert, bail early
300
- if (instructionPaths.length === 0) {
301
- return root;
302
- }
303
-
304
319
  // We'll add the fragmentRefs reference to the root if needed here.
305
320
  var fragmentsOnRoot = (instructionMap[""] || {}).f === "";
306
321
  var unionRootConverter = converters[(instructionMap[""] || {}).u];
@@ -311,9 +326,19 @@ function traverser(
311
326
  return nullableValue;
312
327
  }
313
328
 
329
+ var n = [];
330
+
331
+ // Since a root level union is treated as a "new root level", we'll need
332
+ // to do a separate check here of whether there's a fragment on the root
333
+ // we need to account for, or not.
334
+ if (unionRootConverter != null) {
335
+ n = [v.__typename];
336
+ fragmentsOnRoot = (instructionMap[v.__typename] || {}).f === "";
337
+ }
338
+
314
339
  var traversedObj = traverse(
315
340
  instructionMaps,
316
- [],
341
+ n,
317
342
  v,
318
343
  instructionMap,
319
344
  converters,
@@ -330,9 +355,18 @@ function traverser(
330
355
 
331
356
  var newObj = Object.assign({}, root);
332
357
 
358
+ var n = [];
359
+
360
+ // Same as in the union array check above - if there's a fragment in the new
361
+ // root created by the union, we need to account for that separately here.
362
+ if (unionRootConverter != null) {
363
+ n = [newObj.__typename];
364
+ fragmentsOnRoot = (instructionMap[newObj.__typename] || {}).f === "";
365
+ }
366
+
333
367
  var v = traverse(
334
368
  instructionMaps,
335
- [],
369
+ n,
336
370
  newObj,
337
371
  instructionMap,
338
372
  converters,