relay-runtime 1.3.0 → 1.5.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.
Files changed (90) hide show
  1. package/LICENSE +16 -26
  2. package/index.js +3 -6
  3. package/lib/ConvertToExecuteFunction.js +73 -0
  4. package/lib/RelayConcreteNode.js +31 -14
  5. package/lib/RelayConcreteVariables.js +11 -6
  6. package/lib/RelayConnectionHandler.js +2 -4
  7. package/lib/RelayConnectionInterface.js +3 -5
  8. package/lib/RelayCore.js +4 -6
  9. package/lib/RelayDataLoader.js +2 -4
  10. package/lib/RelayDeclarativeMutationConfig.js +316 -0
  11. package/lib/RelayDefaultHandleKey.js +2 -4
  12. package/lib/RelayDefaultHandlerProvider.js +2 -4
  13. package/lib/RelayError.js +2 -6
  14. package/lib/RelayInMemoryRecordSource.js +2 -4
  15. package/lib/RelayInternalTypes.js +2 -5
  16. package/lib/RelayInternals.js +2 -5
  17. package/lib/RelayMarkSweepStore.js +22 -5
  18. package/lib/RelayMetricsRecorder.js +9 -9
  19. package/lib/RelayMockRenderer.js +3 -8
  20. package/lib/RelayModernEnvironment.js +120 -135
  21. package/lib/RelayModernFragmentSpecResolver.js +81 -55
  22. package/lib/RelayModernGraphQLTag.js +8 -17
  23. package/lib/RelayModernOperationSelector.js +8 -8
  24. package/lib/RelayModernRecord.js +8 -8
  25. package/lib/RelayModernSelector.js +54 -43
  26. package/lib/RelayNetwork.js +9 -11
  27. package/lib/RelayNetworkDebug.js +4 -7
  28. package/lib/RelayNetworkLogger.js +2 -4
  29. package/lib/RelayNetworkLoggerTransaction.js +18 -20
  30. package/lib/RelayNetworkTypes.js +2 -4
  31. package/lib/RelayObservable.js +193 -120
  32. package/lib/RelayProfiler.js +7 -7
  33. package/lib/RelayPublishQueue.js +17 -9
  34. package/lib/RelayQueryCaching.js +2 -5
  35. package/lib/RelayQueryResponseCache.js +3 -5
  36. package/lib/RelayReader.js +18 -8
  37. package/lib/RelayRecordProxy.js +12 -11
  38. package/lib/RelayRecordSourceMutator.js +9 -9
  39. package/lib/RelayRecordSourceProxy.js +15 -13
  40. package/lib/RelayRecordSourceSelectorProxy.js +2 -4
  41. package/lib/RelayRecordState.js +2 -4
  42. package/lib/RelayReferenceMarker.js +2 -4
  43. package/lib/RelayResponseNormalizer.js +34 -25
  44. package/lib/RelayRuntime.js +25 -14
  45. package/lib/RelayRuntimeTypes.js +22 -0
  46. package/lib/RelayShallowMock.js +4 -7
  47. package/lib/RelayStoreTypes.js +2 -4
  48. package/lib/RelayStoreUtils.js +66 -26
  49. package/lib/RelayTaskQueue.js +2 -5
  50. package/lib/RelayTypes.js +2 -5
  51. package/lib/RelayViewerHandler.js +4 -5
  52. package/lib/applyRelayModernOptimisticMutation.js +9 -8
  53. package/lib/cloneRelayHandleSourceField.js +4 -11
  54. package/lib/commitLocalUpdate.js +2 -4
  55. package/lib/commitRelayModernMutation.js +24 -22
  56. package/lib/createRelayNetworkLogger.js +25 -27
  57. package/lib/dedent.js +2 -5
  58. package/lib/deepFreeze.js +3 -5
  59. package/lib/deferrableFragmentKey.js +21 -0
  60. package/lib/fetchRelayModernQuery.js +13 -21
  61. package/lib/generateRelayClientID.js +2 -4
  62. package/lib/getRelayHandleKey.js +2 -4
  63. package/lib/hasOverlappingIDs.js +2 -4
  64. package/lib/isCompatibleRelayFragmentType.js +2 -5
  65. package/lib/isPromise.js +2 -5
  66. package/lib/isRelayModernEnvironment.js +2 -4
  67. package/lib/isScalarAndEqual.js +3 -5
  68. package/lib/normalizePayload.js +10 -13
  69. package/lib/normalizeRelayPayload.js +8 -5
  70. package/lib/recycleNodesInto.js +2 -4
  71. package/lib/relayUnstableBatchedUpdates.js +2 -5
  72. package/lib/relayUnstableBatchedUpdates.native.js +2 -5
  73. package/lib/requestRelaySubscription.js +20 -34
  74. package/lib/simpleClone.js +2 -4
  75. package/lib/stableCopy.js +35 -0
  76. package/lib/testEditDistance.js +2 -5
  77. package/lib/throwFailedPromise.js +2 -5
  78. package/package.json +4 -5
  79. package/relay-runtime.js +2307 -2665
  80. package/relay-runtime.min.js +6 -9
  81. package/ARCHITECTURE.md +0 -232
  82. package/PATENTS +0 -33
  83. package/lib/ConvertToObserveFunction.js +0 -39
  84. package/lib/RelayDebugger.js +0 -199
  85. package/lib/RelayRecordSourceInspector.js +0 -289
  86. package/lib/RelayStoreProxyDebugger.js +0 -44
  87. package/lib/formatStorageKey.js +0 -37
  88. package/lib/prettyStringify.js +0 -35
  89. package/lib/setRelayModernMutationConfigs.js +0 -302
  90. package/lib/stableJSONStringify.js +0 -45
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * Copyright (c) 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
3
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
8
6
  *
9
7
  * @providesModule RelayObservable
10
8
  *
@@ -17,9 +15,44 @@ var _classCallCheck3 = _interopRequireDefault(require('babel-runtime/helpers/cla
17
15
 
18
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
19
17
 
18
+ /**
19
+ * A Subscription object is returned from .subscribe(), which can be
20
+ * unsubscribed or checked to see if the resulting subscription has closed.
21
+ */
22
+
23
+
24
+ /**
25
+ * An Observer is an object of optional callback functions provided to
26
+ * .subscribe(). Each callback function is invoked when that event occurs.
27
+ */
28
+
29
+
30
+ /**
31
+ * A Sink is an object of methods provided by Observable during construction.
32
+ * The methods are to be called to trigger each event. It also contains a closed
33
+ * field to see if the resulting subscription has closed.
34
+ */
35
+
36
+
37
+ /**
38
+ * A Source is the required argument when constructing a new Observable. Similar
39
+ * to a Promise constructor, this is a function which is invoked with a Sink,
40
+ * and may return either a cleanup function or a Subscription instance (for use
41
+ * when composing Observables).
42
+ */
43
+
44
+
45
+ /**
46
+ * A Subscribable is an interface describing any object which can be subscribed.
47
+ *
48
+ * Note: A sink may be passed directly to .subscribe() as its observer,
49
+ * allowing for easily composing Subscribables.
50
+ */
51
+
52
+
20
53
  // Note: This should accept Subscribable<T> instead of RelayObservable<T>,
21
54
  // however Flow cannot yet distinguish it from T.
22
- var hostReportError = void 0;
55
+ var hostReportError = swallowError;
23
56
 
24
57
  /**
25
58
  * Limited implementation of ESObservable, providing the limited set of behavior
@@ -34,6 +67,13 @@ var hostReportError = void 0;
34
67
  */
35
68
 
36
69
  var RelayObservable = function () {
70
+ RelayObservable.create = function create(source) {
71
+ return new RelayObservable(source);
72
+ };
73
+
74
+ // Use RelayObservable.create()
75
+
76
+
37
77
  function RelayObservable(source) {
38
78
  (0, _classCallCheck3['default'])(this, RelayObservable);
39
79
 
@@ -47,16 +87,29 @@ var RelayObservable = function () {
47
87
  }
48
88
 
49
89
  /**
50
- * When an unhandled error is detected, it is reported to the host environment
51
- * (the ESObservable spec refers to this method as "HostReportErrors()").
90
+ * When an emitted error event is not handled by an Observer, it is reported
91
+ * to the host environment (what the ESObservable spec refers to as
92
+ * "HostReportErrors()").
52
93
  *
53
- * The default implementation in development builds re-throws errors in a
54
- * separate frame, and from production builds does nothing (swallowing
55
- * uncaught errors).
94
+ * The default implementation in development rethrows thrown errors, and
95
+ * logs emitted error events to the console, while in production does nothing
96
+ * (swallowing unhandled errors).
56
97
  *
57
98
  * Called during application initialization, this method allows
58
- * application-specific handling of uncaught errors. Allowing, for example,
99
+ * application-specific handling of unhandled errors. Allowing, for example,
59
100
  * integration with error logging or developer tools.
101
+ *
102
+ * A second parameter `isUncaughtThrownError` is true when the unhandled error
103
+ * was thrown within an Observer handler, and false when the unhandled error
104
+ * was an unhandled emitted event.
105
+ *
106
+ * - Uncaught thrown errors typically represent avoidable errors thrown from
107
+ * application code, which should be handled with a try/catch block, and
108
+ * usually have useful stack traces.
109
+ *
110
+ * - Unhandled emitted event errors typically represent unavoidable events in
111
+ * application flow such as network failure, and may not have useful
112
+ * stack traces.
60
113
  */
61
114
 
62
115
 
@@ -71,7 +124,7 @@ var RelayObservable = function () {
71
124
 
72
125
 
73
126
  RelayObservable.from = function from(obj) {
74
- return isObservable(obj) ? fromObservable(obj) : require('./isPromise')(obj) ? fromPromise(obj) : obj instanceof Error ? fromError(obj) : fromValue(obj);
127
+ return isObservable(obj) ? fromObservable(obj) : require('./isPromise')(obj) ? fromPromise(obj) : fromValue(obj);
75
128
  };
76
129
 
77
130
  /**
@@ -84,7 +137,7 @@ var RelayObservable = function () {
84
137
 
85
138
 
86
139
  RelayObservable.fromLegacy = function fromLegacy(callback) {
87
- return new RelayObservable(function (sink) {
140
+ return RelayObservable.create(function (sink) {
88
141
  var result = callback({
89
142
  onNext: sink.next,
90
143
  onError: sink.error,
@@ -108,7 +161,7 @@ var RelayObservable = function () {
108
161
  RelayObservable.prototype['catch'] = function _catch(fn) {
109
162
  var _this = this;
110
163
 
111
- return new RelayObservable(function (sink) {
164
+ return RelayObservable.create(function (sink) {
112
165
  var subscription = void 0;
113
166
  _this.subscribe({
114
167
  start: function start(sub) {
@@ -116,13 +169,13 @@ var RelayObservable = function () {
116
169
  },
117
170
  next: sink.next,
118
171
  complete: sink.complete,
119
- error: function (_error) {
172
+ error: function (_error2) {
120
173
  function error(_x) {
121
- return _error.apply(this, arguments);
174
+ return _error2.apply(this, arguments);
122
175
  }
123
176
 
124
177
  error.toString = function () {
125
- return _error.toString();
178
+ return _error2.toString();
126
179
  };
127
180
 
128
181
  return error;
@@ -137,7 +190,7 @@ var RelayObservable = function () {
137
190
  error: sink.error
138
191
  });
139
192
  } catch (error2) {
140
- sink.error(error2);
193
+ sink.error(error2, true /* isUncaughtThrownError */);
141
194
  }
142
195
  })
143
196
  });
@@ -153,7 +206,7 @@ var RelayObservable = function () {
153
206
  * for all events emitted by the source.
154
207
  *
155
208
  * Any errors that are thrown in the side-effect Observer are unhandled, and
156
- * do not effect the source Observable or its Observer.
209
+ * do not affect the source Observable or its Observer.
157
210
  *
158
211
  * This is useful for when debugging your Observables or performing other
159
212
  * side-effects such as logging or performance monitoring.
@@ -163,13 +216,13 @@ var RelayObservable = function () {
163
216
  RelayObservable.prototype['do'] = function _do(observer) {
164
217
  var _this2 = this;
165
218
 
166
- return new RelayObservable(function (sink) {
219
+ return RelayObservable.create(function (sink) {
167
220
  var both = function both(action) {
168
221
  return function () {
169
222
  try {
170
223
  observer[action] && observer[action].apply(observer, arguments);
171
224
  } catch (error) {
172
- handleError(error);
225
+ hostReportError(error, true /* isUncaughtThrownError */);
173
226
  }
174
227
  sink[action] && sink[action].apply(sink, arguments);
175
228
  };
@@ -184,6 +237,27 @@ var RelayObservable = function () {
184
237
  });
185
238
  };
186
239
 
240
+ /**
241
+ * Returns a new Observable which returns the same values as this one, but
242
+ * modified so that the finally callback is performed after completion,
243
+ * whether normal or due to error or unsubscription.
244
+ *
245
+ * This is useful for cleanup such as resource finalization.
246
+ */
247
+
248
+
249
+ RelayObservable.prototype['finally'] = function _finally(fn) {
250
+ var _this3 = this;
251
+
252
+ return RelayObservable.create(function (sink) {
253
+ var subscription = _this3.subscribe(sink);
254
+ return function () {
255
+ subscription.unsubscribe();
256
+ fn();
257
+ };
258
+ });
259
+ };
260
+
187
261
  /**
188
262
  * Returns a new Observable which is identical to this one, unless this
189
263
  * Observable completes before yielding any values, in which case the new
@@ -197,11 +271,11 @@ var RelayObservable = function () {
197
271
 
198
272
 
199
273
  RelayObservable.prototype.ifEmpty = function ifEmpty(alternate) {
200
- var _this3 = this;
274
+ var _this4 = this;
201
275
 
202
- return new RelayObservable(function (sink) {
276
+ return RelayObservable.create(function (sink) {
203
277
  var hasValue = false;
204
- var current = _this3.subscribe({
278
+ var current = _this4.subscribe({
205
279
  next: function next(value) {
206
280
  hasValue = true;
207
281
  sink.next(value);
@@ -225,6 +299,9 @@ var RelayObservable = function () {
225
299
  /**
226
300
  * Observable's primary API: returns an unsubscribable Subscription to the
227
301
  * source of this Observable.
302
+ *
303
+ * Note: A sink may be passed directly to .subscribe() as its observer,
304
+ * allowing for easily composing Observables.
228
305
  */
229
306
 
230
307
 
@@ -261,7 +338,7 @@ var RelayObservable = function () {
261
338
 
262
339
 
263
340
  RelayObservable.prototype.map = function map(fn) {
264
- return this.concatMap(function (value) {
341
+ return this.mergeMap(function (value) {
265
342
  return fromValue(fn(value));
266
343
  });
267
344
  };
@@ -269,66 +346,54 @@ var RelayObservable = function () {
269
346
  /**
270
347
  * Returns a new Observable where each value is replaced with a new Observable
271
348
  * by the mapping function, the results of which returned as a single
272
- * concattenated Observable.
349
+ * merged Observable.
273
350
  */
274
351
 
275
352
 
276
- RelayObservable.prototype.concatMap = function concatMap(fn) {
277
- var _this4 = this;
353
+ RelayObservable.prototype.mergeMap = function mergeMap(fn) {
354
+ var _this5 = this;
278
355
 
279
- return new RelayObservable(function (sink) {
280
- var hasCompleted = false;
281
- var outer = void 0;
282
- var inner = void 0;
283
- var buffer = [];
356
+ return RelayObservable.create(function (sink) {
357
+ var subscriptions = [];
284
358
 
285
- function next(value) {
286
- if (inner) {
287
- buffer.push(value);
288
- } else {
289
- try {
290
- RelayObservable.from(fn(value)).subscribe({
291
- start: function start(sub) {
292
- inner = sub;
293
- },
294
- next: sink.next,
295
- error: sink.error,
296
- complete: function complete() {
297
- inner = undefined;
298
- if (buffer.length !== 0) {
299
- next(buffer.shift());
300
- } else if (hasCompleted) {
301
- sink.complete();
302
- }
303
- }
304
- });
305
- } catch (error) {
306
- sink.error(error);
307
- }
359
+ function start(subscription) {
360
+ this._sub = subscription;
361
+ subscriptions.push(subscription);
362
+ }
363
+
364
+ function complete() {
365
+ subscriptions.splice(subscriptions.indexOf(this._sub), 1);
366
+ if (subscriptions.length === 0) {
367
+ sink.complete();
308
368
  }
309
369
  }
310
370
 
311
- _this4.subscribe({
312
- start: function start(sub) {
313
- outer = sub;
371
+ _this5.subscribe({
372
+ start: start,
373
+ next: function next(value) {
374
+ try {
375
+ if (!sink.closed) {
376
+ RelayObservable.from(fn(value)).subscribe({
377
+ start: start,
378
+ next: sink.next,
379
+ error: sink.error,
380
+ complete: complete
381
+ });
382
+ }
383
+ } catch (error) {
384
+ sink.error(error, true /* isUncaughtThrownError */);
385
+ }
314
386
  },
315
- next: next,
387
+
316
388
  error: sink.error,
317
- complete: function complete() {
318
- hasCompleted = true;
319
- if (!inner) {
320
- sink.complete();
321
- }
322
- }
389
+ complete: complete
323
390
  });
324
391
 
325
392
  return function () {
326
- if (inner) {
327
- inner.unsubscribe();
328
- inner = undefined;
329
- }
330
- outer.unsubscribe();
331
- buffer.length = 0;
393
+ subscriptions.forEach(function (sub) {
394
+ return sub.unsubscribe();
395
+ });
396
+ subscriptions.length = 0;
332
397
  };
333
398
  });
334
399
  };
@@ -343,18 +408,18 @@ var RelayObservable = function () {
343
408
 
344
409
 
345
410
  RelayObservable.prototype.poll = function poll(pollInterval) {
346
- var _this5 = this;
411
+ var _this6 = this;
347
412
 
348
413
  if (process.env.NODE_ENV !== 'production') {
349
414
  if (typeof pollInterval !== 'number' || pollInterval <= 0) {
350
415
  throw new Error('RelayObservable: Expected pollInterval to be positive, got: ' + pollInterval);
351
416
  }
352
417
  }
353
- return new RelayObservable(function (sink) {
418
+ return RelayObservable.create(function (sink) {
354
419
  var subscription = void 0;
355
420
  var timeout = void 0;
356
421
  var poll = function poll() {
357
- subscription = _this5.subscribe({
422
+ subscription = _this6.subscribe({
358
423
  next: sink.next,
359
424
  error: sink.error,
360
425
  complete: function complete() {
@@ -377,11 +442,11 @@ var RelayObservable = function () {
377
442
 
378
443
 
379
444
  RelayObservable.prototype.toPromise = function toPromise() {
380
- var _this6 = this;
445
+ var _this7 = this;
381
446
 
382
447
  return new Promise(function (resolve, reject) {
383
448
  var subscription = void 0;
384
- _this6.subscribe({
449
+ _this7.subscribe({
385
450
  start: function start(sub) {
386
451
  subscription = sub;
387
452
  },
@@ -402,19 +467,18 @@ var RelayObservable = function () {
402
467
  // Use declarations to teach Flow how to check isObservable.
403
468
 
404
469
 
405
- // eslint-disable-next-line no-redeclare
406
470
  function isObservable(obj) {
407
471
  return typeof obj === 'object' && obj !== null && typeof obj.subscribe === 'function';
408
472
  }
409
473
 
410
474
  function fromObservable(obj) {
411
- return obj instanceof RelayObservable ? obj : new RelayObservable(function (sink) {
475
+ return obj instanceof RelayObservable ? obj : RelayObservable.create(function (sink) {
412
476
  return obj.subscribe(sink);
413
477
  });
414
478
  }
415
479
 
416
480
  function fromPromise(promise) {
417
- return new RelayObservable(function (sink) {
481
+ return RelayObservable.create(function (sink) {
418
482
  // Since sink methods do not throw, the resulting Promise can be ignored.
419
483
  promise.then(function (value) {
420
484
  sink.next(value);
@@ -424,26 +488,26 @@ function fromPromise(promise) {
424
488
  }
425
489
 
426
490
  function fromValue(value) {
427
- return new RelayObservable(function (sink) {
491
+ return RelayObservable.create(function (sink) {
428
492
  sink.next(value);
429
493
  sink.complete();
430
494
  });
431
495
  }
432
496
 
433
- function fromError(error) {
434
- return new RelayObservable(function (sink) {
435
- sink.error(error);
436
- });
437
- }
438
-
439
- function handleError(error) {
440
- hostReportError && hostReportError(error);
441
- }
442
-
443
497
  function _subscribe(source, observer) {
444
498
  var closed = false;
445
499
  var cleanup = void 0;
446
500
 
501
+ // Ideally we would simply describe a `get closed()` method on the Sink and
502
+ // Subscription objects below, however not all flow environments we expect
503
+ // Relay to be used within will support property getters, and many minifier
504
+ // tools still do not support ES5 syntax. Instead, we can use defineProperty.
505
+ var withClosed = function withClosed(obj) {
506
+ return Object.defineProperty(obj, 'closed', { get: function get() {
507
+ return closed;
508
+ } });
509
+ };
510
+
447
511
  function doCleanup() {
448
512
  if (cleanup) {
449
513
  if (cleanup.unsubscribe) {
@@ -452,7 +516,7 @@ function _subscribe(source, observer) {
452
516
  try {
453
517
  cleanup();
454
518
  } catch (error) {
455
- handleError(error);
519
+ hostReportError(error, true /* isUncaughtThrownError */);
456
520
  }
457
521
  }
458
522
  cleanup = undefined;
@@ -460,7 +524,7 @@ function _subscribe(source, observer) {
460
524
  }
461
525
 
462
526
  // Create a Subscription.
463
- var subscription = {
527
+ var subscription = withClosed({
464
528
  unsubscribe: function unsubscribe() {
465
529
  if (!closed) {
466
530
  closed = true;
@@ -469,19 +533,19 @@ function _subscribe(source, observer) {
469
533
  try {
470
534
  observer.unsubscribe && observer.unsubscribe(subscription);
471
535
  } catch (error) {
472
- handleError(error);
536
+ hostReportError(error, true /* isUncaughtThrownError */);
473
537
  } finally {
474
538
  doCleanup();
475
539
  }
476
540
  }
477
541
  }
478
- };
542
+ });
479
543
 
480
544
  // Tell Observer that observation is about to begin.
481
545
  try {
482
546
  observer.start && observer.start(subscription);
483
547
  } catch (error) {
484
- handleError(error);
548
+ hostReportError(error, true /* isUncaughtThrownError */);
485
549
  }
486
550
 
487
551
  // If closed already, don't bother creating a Sink.
@@ -490,40 +554,40 @@ function _subscribe(source, observer) {
490
554
  }
491
555
 
492
556
  // Create a Sink respecting subscription state and cleanup.
493
- var sink = {
557
+ var sink = withClosed({
494
558
  next: function next(value) {
495
559
  if (!closed && observer.next) {
496
560
  try {
497
561
  observer.next(value);
498
562
  } catch (error) {
499
- handleError(error);
563
+ hostReportError(error, true /* isUncaughtThrownError */);
500
564
  }
501
565
  }
502
566
  },
503
- error: function (_error2) {
504
- function error(_x2) {
505
- return _error2.apply(this, arguments);
567
+ error: function (_error3) {
568
+ function error(_x2, _x3) {
569
+ return _error3.apply(this, arguments);
506
570
  }
507
571
 
508
572
  error.toString = function () {
509
- return _error2.toString();
573
+ return _error3.toString();
510
574
  };
511
575
 
512
576
  return error;
513
- }(function (error) {
514
- try {
515
- if (closed) {
516
- throw error;
517
- }
577
+ }(function (error, isUncaughtThrownError) {
578
+ if (closed || !observer.error) {
518
579
  closed = true;
519
- if (!observer.error) {
520
- throw error;
521
- }
522
- observer.error(error);
523
- } catch (error2) {
524
- handleError(error2);
525
- } finally {
580
+ hostReportError(error, isUncaughtThrownError || false);
526
581
  doCleanup();
582
+ } else {
583
+ closed = true;
584
+ try {
585
+ observer.error(error);
586
+ } catch (error2) {
587
+ hostReportError(error2, true /* isUncaughtThrownError */);
588
+ } finally {
589
+ doCleanup();
590
+ }
527
591
  }
528
592
  }),
529
593
  complete: function complete() {
@@ -532,19 +596,19 @@ function _subscribe(source, observer) {
532
596
  try {
533
597
  observer.complete && observer.complete();
534
598
  } catch (error) {
535
- handleError(error);
599
+ hostReportError(error, true /* isUncaughtThrownError */);
536
600
  } finally {
537
601
  doCleanup();
538
602
  }
539
603
  }
540
604
  }
541
- };
605
+ });
542
606
 
543
607
  // If anything goes wrong during observing the source, handle the error.
544
608
  try {
545
609
  cleanup = source(sink);
546
610
  } catch (error) {
547
- sink.error(error);
611
+ sink.error(error, true /* isUncaughtThrownError */);
548
612
  }
549
613
 
550
614
  if (process.env.NODE_ENV !== 'production') {
@@ -562,18 +626,27 @@ function _subscribe(source, observer) {
562
626
  return subscription;
563
627
  }
564
628
 
629
+ function swallowError(_error, _isUncaughtThrownError) {
630
+ // do nothing.
631
+ }
632
+
565
633
  if (process.env.NODE_ENV !== 'production') {
566
634
  // Default implementation of HostReportErrors() in development builds.
567
635
  // Can be replaced by the host application environment.
568
- RelayObservable.onUnhandledError(function (error) {
636
+ RelayObservable.onUnhandledError(function (error, isUncaughtThrownError) {
569
637
  if (typeof fail === 'function') {
570
638
  // In test environments (Jest), fail() immediately fails the current test.
571
639
  fail(String(error));
572
- } else {
573
- // Otherwise, rethrow on the next frame to avoid breaking current logic.
640
+ } else if (isUncaughtThrownError) {
641
+ // Rethrow uncaught thrown errors on the next frame to avoid breaking
642
+ // current logic.
574
643
  setTimeout(function () {
575
644
  throw error;
576
645
  });
646
+ } else if (typeof console !== 'undefined') {
647
+ // Otherwise, log the unhandled error for visibility.
648
+ // eslint-ignore-next-line no-console
649
+ console.error('RelayObservable: Unhandled Error', error);
577
650
  }
578
651
  });
579
652
  }
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * Copyright (c) 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
3
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
8
6
  *
9
7
  * @providesModule RelayProfiler
10
8
  *
@@ -78,9 +76,11 @@ var RelayProfiler = {
78
76
  * `attachHandler` and `detachHandler` methods.
79
77
  */
80
78
  instrumentMethods: function instrumentMethods(object, names) {
81
- require('fbjs/lib/forEachObject')(names, function (name, key) {
82
- object[key] = RelayProfiler.instrument(name, object[key]);
83
- });
79
+ for (var _key in names) {
80
+ if (names.hasOwnProperty(_key)) {
81
+ object[_key] = RelayProfiler.instrument(names[_key], object[_key]);
82
+ }
83
+ }
84
84
  },
85
85
 
86
86
 
@@ -1,10 +1,8 @@
1
1
  /**
2
2
  * Copyright (c) 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
3
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
8
6
  *
9
7
  *
10
8
  * @providesModule RelayPublishQueue
@@ -237,10 +235,15 @@ var RelayPublishQueue = function () {
237
235
  selectorData = lookupSelector(_source, _operation.fragment);
238
236
  }
239
237
  selectorStoreUpdater && selectorStoreUpdater(selectorStore, selectorData);
240
- } else {
238
+ } else if (optimisticUpdate.storeUpdater) {
241
239
  var storeUpdater = optimisticUpdate.storeUpdater;
242
240
 
243
241
  storeUpdater(store);
242
+ } else {
243
+ var _source2 = optimisticUpdate.source,
244
+ _fieldPayloads = optimisticUpdate.fieldPayloads;
245
+
246
+ store.publishSource(_source2, _fieldPayloads);
244
247
  }
245
248
  });
246
249
  }
@@ -256,19 +259,24 @@ var RelayPublishQueue = function () {
256
259
  var selectorStore = store.commitPayload(_operation2, response);
257
260
  // TODO: Fix commitPayload so we don't have to run normalize twice
258
261
  var selectorData = void 0,
259
- _source2 = void 0;
262
+ _source3 = void 0;
260
263
  if (response) {
261
264
  var _normalizeRelayPayloa2 = require('./normalizeRelayPayload')(_operation2.root, response);
262
265
 
263
- _source2 = _normalizeRelayPayloa2.source;
266
+ _source3 = _normalizeRelayPayloa2.source;
264
267
 
265
- selectorData = lookupSelector(_source2, _operation2.fragment);
268
+ selectorData = lookupSelector(_source3, _operation2.fragment);
266
269
  }
267
270
  selectorStoreUpdater && selectorStoreUpdater(selectorStore, selectorData);
268
- } else {
271
+ } else if (optimisticUpdate.storeUpdater) {
269
272
  var storeUpdater = optimisticUpdate.storeUpdater;
270
273
 
271
274
  storeUpdater(store);
275
+ } else {
276
+ var _source4 = optimisticUpdate.source,
277
+ _fieldPayloads2 = optimisticUpdate.fieldPayloads;
278
+
279
+ store.publishSource(_source4, _fieldPayloads2);
272
280
  }
273
281
  _this4._appliedOptimisticUpdates.add(optimisticUpdate);
274
282
  });
@@ -1,12 +1,9 @@
1
1
  /**
2
2
  * Copyright (c) 2013-present, Facebook, Inc.
3
- * All rights reserved.
4
3
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
8
6
  *
9
- * @providesModule RelayQueryCaching
10
7
  *
11
8
  * @format
12
9
  */